pax_global_header00006660000000000000000000000064151335467020014520gustar00rootroot0000000000000052 comment=6b508042c3e707197c6c920bc67b26f1c8e11d5b gift-0.2.0/000077500000000000000000000000001513354670200124505ustar00rootroot00000000000000gift-0.2.0/.github/000077500000000000000000000000001513354670200140105ustar00rootroot00000000000000gift-0.2.0/.github/workflows/000077500000000000000000000000001513354670200160455ustar00rootroot00000000000000gift-0.2.0/.github/workflows/test.yml000066400000000000000000000020521513354670200175460ustar00rootroot00000000000000on: push: branches: [master] pull_request: permissions: contents: read name: Test jobs: test: strategy: matrix: go-version: [1.24.x, 1.25.x] platform: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.platform }} steps: - name: Checkout code uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - name: Install Go uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version: ${{ matrix.go-version }} - name: Install staticcheck run: go install honnef.co/go/tools/cmd/staticcheck@latest shell: bash - name: Update PATH run: echo "$(go env GOPATH)/bin" >> $GITHUB_PATH shell: bash - name: Fmt if: matrix.platform == 'ubuntu-latest' run: "diff <(gofmt -d .) <(printf '')" shell: bash - name: Vet run: go vet ./... - name: Staticcheck run: staticcheck ./... - name: Test run: go test -race ./... gift-0.2.0/.gitignore000066400000000000000000000000111513354670200144300ustar00rootroot00000000000000gift.testgift-0.2.0/.travis.yml000066400000000000000000000003311513354670200145560ustar00rootroot00000000000000language: go arch: - AMD64 - ppc64le go: - 1.13.x - 1.14.x - 1.15.x before_install: - go get github.com/mattn/goveralls script: - go test -v -race -cover - $GOPATH/bin/goveralls -service=travis-ci gift-0.2.0/LICENSE000066400000000000000000000021431513354670200134550ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2014-2018 Grigory Dryapak Copyright (c) 2026 The Hugo Authors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. gift-0.2.0/README.md000066400000000000000000000232031513354670200137270ustar00rootroot00000000000000# GO IMAGE FILTERING TOOLKIT (GIFT) [![GoDoc](https://godoc.org/github.com/gohugoio/gift?status.svg)](https://godoc.org/github.com/gohugoio/gift) [![Tests on Linux, MacOS and Windows](https://github.com/gohugoio/gift/workflows/Test/badge.svg)](https://github.com/gohugoio/gift/actions?query=workflow%3ATest) [![Go Report Card](https://goreportcard.com/badge/github.com/gohugoio/gift)](https://goreportcard.com/report/github.com/gohugoio/gift) [![Go Report Card](https://goreportcard.com/badge/github.com/gohugoio/gift)](https://goreportcard.com/report/github.com/gohugoio/gift) *Package gift provides a set of useful image processing filters.* Pure Go. No external dependencies outside of the Go standard library. ### INSTALLATION / UPDATING go get -u github.com/gohugoio/gift ### DOCUMENTATION http://godoc.org/github.com/gohugoio/gift ### QUICK START ```go // 1. Create a new filter list and add some filters. g := gift.New( gift.Resize(800, 0, gift.LanczosResampling), gift.UnsharpMask(1, 1, 0), ) // 2. Create a new image of the corresponding size. // dst is a new target image, src is the original image. dst := image.NewRGBA(g.Bounds(src.Bounds())) // 3. Use the Draw func to apply the filters to src and store the result in dst. g.Draw(dst, src) ``` ### USAGE To create a sequence of filters, the `New` function is used: ```go g := gift.New( gift.Grayscale(), gift.Contrast(10), ) ``` Filters also can be added using the `Add` method: ```go g.Add(GaussianBlur(2)) ``` The `Bounds` method takes the bounds of the source image and returns appropriate bounds for the destination image to fit the result (for example, after using `Resize` or `Rotate` filters). ```go dst := image.NewRGBA(g.Bounds(src.Bounds())) ``` There are two methods available to apply these filters to an image: - `Draw` applies all the added filters to the src image and outputs the result to the dst image starting from the top-left corner (Min point). ```go g.Draw(dst, src) ``` - `DrawAt` provides more control. It outputs the filtered src image to the dst image at the specified position using the specified image composition operator. This example is equivalent to the previous: ```go g.DrawAt(dst, src, dst.Bounds().Min, gift.CopyOperator) ``` Two image composition operators are supported by now: - `CopyOperator` - Replaces pixels of the dst image with pixels of the filtered src image. This mode is used by the Draw method. - `OverOperator` - Places the filtered src image on top of the dst image. This mode makes sence if the filtered src image has transparent areas. Empty filter list can be used to create a copy of an image or to paste one image to another. For example: ```go // Create a new image with dimensions of the bgImage. dstImage := image.NewRGBA(bgImage.Bounds()) // Copy the bgImage to the dstImage. gift.New().Draw(dstImage, bgImage) // Draw the fgImage over the dstImage at the (100, 100) position. gift.New().DrawAt(dstImage, fgImage, image.Pt(100, 100), gift.OverOperator) ``` ### SUPPORTED FILTERS + Transformations - Crop(rect image.Rectangle) - CropToSize(width, height int, anchor Anchor) - FlipHorizontal() - FlipVertical() - Resize(width, height int, resampling Resampling) - ResizeToFill(width, height int, resampling Resampling, anchor Anchor) - ResizeToFit(width, height int, resampling Resampling) - Rotate(angle float32, backgroundColor color.Color, interpolation Interpolation) - Rotate180() - Rotate270() - Rotate90() - Transpose() - Transverse() + Adjustments & effects - Brightness(percentage float32) - ColorBalance(percentageRed, percentageGreen, percentageBlue float32) - ColorFunc(fn func(r0, g0, b0, a0 float32) (r, g, b, a float32)) - Colorize(hue, saturation, percentage float32) - ColorspaceLinearToSRGB() - ColorspaceSRGBToLinear() - Contrast(percentage float32) - Convolution(kernel []float32, normalize, alpha, abs bool, delta float32) - Gamma(gamma float32) - GaussianBlur(sigma float32) - Grayscale() - Hue(shift float32) - Invert() - Maximum(ksize int, disk bool) - Mean(ksize int, disk bool) - Median(ksize int, disk bool) - Minimum(ksize int, disk bool) - Pixelate(size int) - Saturation(percentage float32) - Sepia(percentage float32) - Sigmoid(midpoint, factor float32) - Sobel() - Threshold(percentage float32) - UnsharpMask(sigma, amount, threshold float32) ### FILTER EXAMPLES The original image: ![](testdata/src.png) Resulting images after applying some of the filters: name / result | name / result | name / result | name / result --------------------------------------------|--------------------------------------------|--------------------------------------------|-------------------------------------------- resize | crop_to_size | rotate_180 | rotate_30 ![](testdata/dst_resize.png) | ![](testdata/dst_crop_to_size.png) | ![](testdata/dst_rotate_180.png) | ![](testdata/dst_rotate_30.png) brightness_increase | brightness_decrease | contrast_increase | contrast_decrease ![](testdata/dst_brightness_increase.png) | ![](testdata/dst_brightness_decrease.png) | ![](testdata/dst_contrast_increase.png) | ![](testdata/dst_contrast_decrease.png) saturation_increase | saturation_decrease | gamma_1.5 | gamma_0.5 ![](testdata/dst_saturation_increase.png) | ![](testdata/dst_saturation_decrease.png) | ![](testdata/dst_gamma_1.5.png) | ![](testdata/dst_gamma_0.5.png) gaussian_blur | unsharp_mask | sigmoid | pixelate ![](testdata/dst_gaussian_blur.png) | ![](testdata/dst_unsharp_mask.png) | ![](testdata/dst_sigmoid.png) | ![](testdata/dst_pixelate.png) colorize | grayscale | sepia | invert ![](testdata/dst_colorize.png) | ![](testdata/dst_grayscale.png) | ![](testdata/dst_sepia.png) | ![](testdata/dst_invert.png) mean | median | minimum | maximum ![](testdata/dst_mean.png) | ![](testdata/dst_median.png) | ![](testdata/dst_minimum.png) | ![](testdata/dst_maximum.png) hue_rotate | color_balance | color_func | convolution_emboss ![](testdata/dst_hue_rotate.png) | ![](testdata/dst_color_balance.png) | ![](testdata/dst_color_func.png) | ![](testdata/dst_convolution_emboss.png) Here's the code that produces the above images: ```go package main import ( "image" "image/color" "image/png" "log" "os" "github.com/gohugoio/gift" ) func main() { src := loadImage("testdata/src.png") filters := map[string]gift.Filter{ "resize": gift.Resize(100, 0, gift.LanczosResampling), "crop_to_size": gift.CropToSize(100, 100, gift.LeftAnchor), "rotate_180": gift.Rotate180(), "rotate_30": gift.Rotate(30, color.Transparent, gift.CubicInterpolation), "brightness_increase": gift.Brightness(30), "brightness_decrease": gift.Brightness(-30), "contrast_increase": gift.Contrast(30), "contrast_decrease": gift.Contrast(-30), "saturation_increase": gift.Saturation(50), "saturation_decrease": gift.Saturation(-50), "gamma_1.5": gift.Gamma(1.5), "gamma_0.5": gift.Gamma(0.5), "gaussian_blur": gift.GaussianBlur(1), "unsharp_mask": gift.UnsharpMask(1, 1, 0), "sigmoid": gift.Sigmoid(0.5, 7), "pixelate": gift.Pixelate(5), "colorize": gift.Colorize(240, 50, 100), "grayscale": gift.Grayscale(), "sepia": gift.Sepia(100), "invert": gift.Invert(), "mean": gift.Mean(5, true), "median": gift.Median(5, true), "minimum": gift.Minimum(5, true), "maximum": gift.Maximum(5, true), "hue_rotate": gift.Hue(45), "color_balance": gift.ColorBalance(10, -10, -10), "color_func": gift.ColorFunc( func(r0, g0, b0, a0 float32) (r, g, b, a float32) { r = 1 - r0 // invert the red channel g = g0 + 0.1 // shift the green channel by 0.1 b = 0 // set the blue channel to 0 a = a0 // preserve the alpha channel return r, g, b, a }, ), "convolution_emboss": gift.Convolution( []float32{ -1, -1, 0, -1, 1, 1, 0, 1, 1, }, false, false, false, 0.0, ), } for name, filter := range filters { g := gift.New(filter) dst := image.NewNRGBA(g.Bounds(src.Bounds())) g.Draw(dst, src) saveImage("testdata/dst_"+name+".png", dst) } } func loadImage(filename string) image.Image { f, err := os.Open(filename) if err != nil { log.Fatalf("os.Open failed: %v", err) } defer f.Close() img, _, err := image.Decode(f) if err != nil { log.Fatalf("image.Decode failed: %v", err) } return img } func saveImage(filename string, img image.Image) { f, err := os.Create(filename) if err != nil { log.Fatalf("os.Create failed: %v", err) } defer f.Close() err = png.Encode(f, img) if err != nil { log.Fatalf("png.Encode failed: %v", err) } } ``` gift-0.2.0/colors.go000066400000000000000000000302561513354670200143060ustar00rootroot00000000000000package gift import ( "image" "image/draw" "math" ) func prepareLut(lutSize int, fn func(float32) float32) []float32 { lut := make([]float32, lutSize) q := 1 / float32(lutSize-1) for v := range lutSize { u := float32(v) * q lut[v] = fn(u) } return lut } func getFromLut(lut []float32, u float32) float32 { v := int(u*float32(len(lut)-1) + 0.5) return lut[v] } type colorchanFilter struct { fn func(float32) float32 lut bool } func (p *colorchanFilter) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { dstBounds = image.Rect(0, 0, srcBounds.Dx(), srcBounds.Dy()) return } func (p *colorchanFilter) Draw(dst draw.Image, src image.Image, options *Options) { if options == nil { options = &defaultOptions } srcb := src.Bounds() dstb := dst.Bounds() pixGetter := newPixelGetter(src) pixSetter := newPixelSetter(dst) var useLut bool var lut []float32 useLut = false if p.lut { var lutSize int it := pixGetter.it if it == itNRGBA || it == itRGBA || it == itGray || it == itYCbCr { lutSize = 0xff + 1 } else { lutSize = 0xffff + 1 } numCalculations := srcb.Dx() * srcb.Dy() * 3 if numCalculations > lutSize*2 { useLut = true lut = prepareLut(lutSize, p.fn) } } parallelize(options.Workers, srcb.Min.Y, srcb.Max.Y, func(start, stop int) { for y := start; y < stop; y++ { for x := srcb.Min.X; x < srcb.Max.X; x++ { px := pixGetter.getPixel(x, y) if useLut { px.r = getFromLut(lut, px.r) px.g = getFromLut(lut, px.g) px.b = getFromLut(lut, px.b) } else { px.r = p.fn(px.r) px.g = p.fn(px.g) px.b = p.fn(px.b) } pixSetter.setPixel(dstb.Min.X+x-srcb.Min.X, dstb.Min.Y+y-srcb.Min.Y, px) } } }) } // Invert creates a filter that negates the colors of an image. func Invert() Filter { return &colorchanFilter{ fn: func(x float32) float32 { return 1 - x }, lut: false, } } // ColorspaceSRGBToLinear creates a filter that converts the colors of an image from sRGB to linear RGB. func ColorspaceSRGBToLinear() Filter { return &colorchanFilter{ fn: func(x float32) float32 { if x <= 0.04045 { return x / 12.92 } return float32(math.Pow(float64((x+0.055)/1.055), 2.4)) }, lut: true, } } // ColorspaceLinearToSRGB creates a filter that converts the colors of an image from linear RGB to sRGB. func ColorspaceLinearToSRGB() Filter { return &colorchanFilter{ fn: func(x float32) float32 { if x <= 0.0031308 { return x * 12.92 } return float32(1.055*math.Pow(float64(x), 1/2.4) - 0.055) }, lut: true, } } // Gamma creates a filter that performs a gamma correction on an image. // The gamma parameter must be positive. Gamma = 1 gives the original image. // Gamma less than 1 darkens the image and gamma greater than 1 lightens it. func Gamma(gamma float32) Filter { e := 1 / maxf32(gamma, 1.0e-5) return &colorchanFilter{ fn: func(x float32) float32 { return powf32(x, e) }, lut: true, } } func sigmoid(a, b, x float32) float32 { return 1 / (1 + expf32(b*(a-x))) } // Sigmoid creates a filter that changes the contrast of an image using a sigmoidal function and returns the adjusted image. // It's a non-linear contrast change useful for photo adjustments as it preserves highlight and shadow detail. // The midpoint parameter is the midpoint of contrast that must be between 0 and 1, typically 0.5. // The factor parameter indicates how much to increase or decrease the contrast, typically in range (-10, 10). // If the factor parameter is positive the image contrast is increased otherwise the contrast is decreased. // // Example: // // g := gift.New( // gift.Sigmoid(0.5, 5), // ) // dst := image.NewRGBA(g.Bounds(src.Bounds())) // g.Draw(dst, src) func Sigmoid(midpoint, factor float32) Filter { a := minf32(maxf32(midpoint, 0), 1) b := absf32(factor) sig0 := sigmoid(a, b, 0) sig1 := sigmoid(a, b, 1) e := float32(1.0e-5) return &colorchanFilter{ fn: func(x float32) float32 { if factor == 0 { return x } else if factor > 0 { sig := sigmoid(a, b, x) return (sig - sig0) / (sig1 - sig0) } else { arg := minf32(maxf32((sig1-sig0)*x+sig0, e), 1-e) return a - logf32(1/arg-1)/b } }, lut: true, } } // Contrast creates a filter that changes the contrast of an image. // The percentage parameter must be in range (-100, 100). The percentage = 0 gives the original image. // The percentage = -100 gives solid grey image. The percentage = 100 gives an overcontrasted image. func Contrast(percentage float32) Filter { if percentage == 0 { return ©imageFilter{} } p := 1 + minf32(maxf32(percentage, -100), 100)/100 return &colorchanFilter{ fn: func(x float32) float32 { if 0 <= p && p <= 1 { return 0.5 + (x-0.5)*p } else if 1 < p && p < 2 { return 0.5 + (x-0.5)*(1/(2.0-p)) } else { if x < 0.5 { return 0 } return 1 } }, lut: false, } } // Brightness creates a filter that changes the brightness of an image. // The percentage parameter must be in range (-100, 100). The percentage = 0 gives the original image. // The percentage = -100 gives solid black image. The percentage = 100 gives solid white image. func Brightness(percentage float32) Filter { if percentage == 0 { return ©imageFilter{} } shift := minf32(maxf32(percentage, -100), 100) / 100 return &colorchanFilter{ fn: func(x float32) float32 { return x + shift }, lut: false, } } type colorFilter struct { fn func(pixel) pixel } func (p *colorFilter) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { dstBounds = image.Rect(0, 0, srcBounds.Dx(), srcBounds.Dy()) return } func (p *colorFilter) Draw(dst draw.Image, src image.Image, options *Options) { if options == nil { options = &defaultOptions } srcb := src.Bounds() dstb := dst.Bounds() pixGetter := newPixelGetter(src) pixSetter := newPixelSetter(dst) parallelize(options.Workers, srcb.Min.Y, srcb.Max.Y, func(start, stop int) { for y := start; y < stop; y++ { for x := srcb.Min.X; x < srcb.Max.X; x++ { px := pixGetter.getPixel(x, y) pixSetter.setPixel(dstb.Min.X+x-srcb.Min.X, dstb.Min.Y+y-srcb.Min.Y, p.fn(px)) } } }) } // Grayscale creates a filter that produces a grayscale version of an image. func Grayscale() Filter { return &colorFilter{ fn: func(px pixel) pixel { y := 0.299*px.r + 0.587*px.g + 0.114*px.b return pixel{y, y, y, px.a} }, } } // Sepia creates a filter that produces a sepia-toned version of an image. // The percentage parameter specifies how much the image should be adjusted. It must be in the range (0, 100) // // Example: // // g := gift.New( // gift.Sepia(100), // ) // dst := image.NewRGBA(g.Bounds(src.Bounds())) // g.Draw(dst, src) func Sepia(percentage float32) Filter { adjustAmount := minf32(maxf32(percentage, 0), 100) / 100 rr := 1 - 0.607*adjustAmount rg := 0.769 * adjustAmount rb := 0.189 * adjustAmount gr := 0.349 * adjustAmount gg := 1 - 0.314*adjustAmount gb := 0.168 * adjustAmount br := 0.272 * adjustAmount bg := 0.534 * adjustAmount bb := 1 - 0.869*adjustAmount return &colorFilter{ fn: func(px pixel) pixel { r := px.r*rr + px.g*rg + px.b*rb g := px.r*gr + px.g*gg + px.b*gb b := px.r*br + px.g*bg + px.b*bb return pixel{r, g, b, px.a} }, } } func convertHSLToRGB(h, s, l float32) (float32, float32, float32) { if s == 0 { return l, l, l } hueToRGB := func(p, q, t float32) float32 { if t < 0 { t++ } if t > 1 { t-- } if t < 1/6.0 { return p + (q-p)*6*t } if t < 1/2.0 { return q } if t < 2/3.0 { return p + (q-p)*(2/3.0-t)*6 } return p } var p, q float32 if l < 0.5 { q = l * (1 + s) } else { q = l + s - l*s } p = 2*l - q r := hueToRGB(p, q, h+1/3.0) g := hueToRGB(p, q, h) b := hueToRGB(p, q, h-1/3.0) return r, g, b } func convertRGBToHSL(r, g, b float32) (float32, float32, float32) { max := maxf32(r, maxf32(g, b)) min := minf32(r, minf32(g, b)) l := (max + min) / 2 if max == min { return 0, 0, l } var h, s float32 d := max - min if l > 0.5 { s = d / (2 - max - min) } else { s = d / (max + min) } if r == max { h = (g - b) / d if g < b { h += 6 } } else if g == max { h = (b-r)/d + 2 } else { h = (r-g)/d + 4 } h /= 6 return h, s, l } func normalizeHue(hue float32) float32 { hue = hue - float32(int(hue)) if hue < 0 { hue++ } return hue } // Hue creates a filter that rotates the hue of an image. // The shift parameter is the hue angle shift, typically in range (-180, 180). // The shift = 0 gives the original image. func Hue(shift float32) Filter { p := normalizeHue(shift / 360) if p == 0 { return ©imageFilter{} } return &colorFilter{ fn: func(px pixel) pixel { h, s, l := convertRGBToHSL(px.r, px.g, px.b) h = normalizeHue(h + p) r, g, b := convertHSLToRGB(h, s, l) return pixel{r, g, b, px.a} }, } } // Saturation creates a filter that changes the saturation of an image. // The percentage parameter must be in range (-100, 500). The percentage = 0 gives the original image. func Saturation(percentage float32) Filter { p := 1 + minf32(maxf32(percentage, -100), 500)/100 if p == 1 { return ©imageFilter{} } return &colorFilter{ fn: func(px pixel) pixel { h, s, l := convertRGBToHSL(px.r, px.g, px.b) s *= p if s > 1 { s = 1 } r, g, b := convertHSLToRGB(h, s, l) return pixel{r, g, b, px.a} }, } } // Colorize creates a filter that produces a colorized version of an image. // The hue parameter is the angle on the color wheel, typically in range (0, 360). // The saturation parameter must be in range (0, 100). // The percentage parameter specifies the strength of the effect, it must be in range (0, 100). // // Example: // // g := gift.New( // gift.Colorize(240, 50, 100), // blue colorization, 50% saturation // ) // dst := image.NewRGBA(g.Bounds(src.Bounds())) // g.Draw(dst, src) func Colorize(hue, saturation, percentage float32) Filter { h := normalizeHue(hue / 360) s := minf32(maxf32(saturation, 0), 100) / 100 p := minf32(maxf32(percentage, 0), 100) / 100 if p == 0 { return ©imageFilter{} } return &colorFilter{ fn: func(px pixel) pixel { _, _, l := convertRGBToHSL(px.r, px.g, px.b) r, g, b := convertHSLToRGB(h, s, l) px.r += (r - px.r) * p px.g += (g - px.g) * p px.b += (b - px.b) * p return px }, } } // ColorBalance creates a filter that changes the color balance of an image. // The percentage parameters for each color channel (red, green, blue) must be in range (-100, 500). // // Example: // // g := gift.New( // gift.ColorBalance(20, -20, 0), // +20% red, -20% green // ) // dst := image.NewRGBA(g.Bounds(src.Bounds())) // g.Draw(dst, src) func ColorBalance(percentageRed, percentageGreen, percentageBlue float32) Filter { pr := 1 + minf32(maxf32(percentageRed, -100), 500)/100 pg := 1 + minf32(maxf32(percentageGreen, -100), 500)/100 pb := 1 + minf32(maxf32(percentageBlue, -100), 500)/100 return &colorFilter{ fn: func(px pixel) pixel { px.r *= pr px.g *= pg px.b *= pb return px }, } } // Threshold creates a filter that applies black/white thresholding to the image. // The percentage parameter must be in range (0, 100). func Threshold(percentage float32) Filter { p := minf32(maxf32(percentage, 0), 100) / 100 return &colorFilter{ fn: func(px pixel) pixel { y := 0.299*px.r + 0.587*px.g + 0.114*px.b if y > p { return pixel{1, 1, 1, px.a} } return pixel{0, 0, 0, px.a} }, } } // ColorFunc creates a filter that changes the colors of an image using custom function. // The fn parameter specifies a function that takes red, green, blue and alpha channels of a pixel // as float32 values in range (0, 1) and returns the modified channel values. // // Example: // // g := gift.New( // gift.ColorFunc( // func(r0, g0, b0, a0 float32) (r, g, b, a float32) { // r = 1 - r0 // invert the red channel // g = g0 + 0.1 // shift the green channel by 0.1 // b = 0 // set the blue channel to 0 // a = a0 // preserve the alpha channel // return r, g, b, a // }, // ), // ) // dst := image.NewRGBA(g.Bounds(src.Bounds())) // g.Draw(dst, src) func ColorFunc(fn func(r0, g0, b0, a0 float32) (r, g, b, a float32)) Filter { return &colorFilter{ fn: func(px pixel) pixel { r, g, b, a := fn(px.r, px.g, px.b, px.a) return pixel{r, g, b, a} }, } } gift-0.2.0/colors_test.go000066400000000000000000000656351513354670200153560ustar00rootroot00000000000000package gift import ( "image" "image/color" "image/draw" "math" "testing" ) func TestLut(t *testing.T) { fn := func(v float32) float32 { return v } for _, size := range []int{10, 100, 1000} { lut := prepareLut(size, fn) l := len(lut) if l != size { t.Errorf("LUT bad size: expected %v got %v", size, l) } if lut[0] != 0 { t.Errorf("LUT bad start value: expected 0 got %v", lut[0]) } if lut[l-1] != 1 { t.Errorf("LUT bad end value: expected 1 got %v", lut[l-1]) } } lut := prepareLut(10000, fn) for _, u := range []float32{0, 0.0001, 0.5555, 0.9999, 1} { v := getFromLut(lut, u) if math.Abs(float64(v-u)) > 0.0001 { t.Errorf("LUT bad value: expected %v got %v", u, v) } } } func TestInvert(t *testing.T) { src := image.NewGray(image.Rect(0, 0, 256, 1)) for i := 0; i <= 255; i++ { src.Pix[i] = uint8(i) } g := New(Invert()) dst := image.NewGray(g.Bounds(src.Bounds())) g.Draw(dst, src) for i := 0; i <= 255; i++ { if dst.Pix[i] != 255-src.Pix[i] { t.Errorf("InvertColors: index %d: expected %d got %d", i, 255-src.Pix[i], dst.Pix[i]) } } } func TestColorspaceSRGBToLinear(t *testing.T) { vals := []float32{ 0.00000, 0.01002, 0.03310, 0.07324, 0.13287, 0.21404, 0.31855, 0.44799, 0.60383, 0.78741, 1.00000, } imgs := []draw.Image{ image.NewGray(image.Rect(0, 0, 11, 11)), image.NewGray(image.Rect(0, 0, 111, 111)), image.NewGray16(image.Rect(0, 0, 11, 11)), image.NewGray16(image.Rect(0, 0, 1111, 1111)), } for _, img := range imgs { for i := 0; i <= 10; i++ { img.Set(i, 0, color.Gray{uint8(255 * i / 10.0)}) } img2 := image.NewGray(img.Bounds()) New(ColorspaceSRGBToLinear()).Draw(img2, img) if !img2.Bounds().Size().Eq(img.Bounds().Size()) { t.Errorf("ColorspaceSRGBToLinear bad result size: expected %v got %v", img.Bounds().Size(), img2.Bounds().Size()) } for i := 0; i <= 10; i++ { expected := uint8(vals[i]*255 + 0.5) c := img2.At(i, 0).(color.Gray) if math.Abs(float64(c.Y)-float64(expected)) > 1 { t.Errorf("ColorspaceSRGBToLinear bad color value at index %v expected %v got %v", i, expected, c.Y) } } } } func TestColorspaceLinearToSRGB(t *testing.T) { vals := []float32{ 0.00000, 0.34919, 0.48453, 0.58383, 0.66519, 0.73536, 0.79774, 0.85431, 0.90633, 0.95469, 1.00000, } imgs := []draw.Image{ image.NewGray(image.Rect(0, 0, 11, 11)), image.NewGray(image.Rect(0, 0, 111, 111)), image.NewGray16(image.Rect(0, 0, 11, 11)), image.NewGray16(image.Rect(0, 0, 1111, 1111)), } for _, img := range imgs { for i := 0; i <= 10; i++ { img.Set(i, 0, color.Gray{uint8(255 * i / 10.0)}) } img2 := image.NewGray(img.Bounds()) New(ColorspaceLinearToSRGB()).Draw(img2, img) if !img2.Bounds().Size().Eq(img.Bounds().Size()) { t.Errorf("ColorspaceLinearRGBToSRGB bad result size: expected %v got %v", img.Bounds().Size(), img2.Bounds().Size()) } for i := 0; i <= 10; i++ { expected := uint8(vals[i]*255 + 0.5) c := img2.At(i, 0).(color.Gray) if math.Abs(float64(c.Y)-float64(expected)) > 1 { t.Errorf("ColorspaceLinearRGBToSRGB bad color value at index %v expected %v got %v", i, expected, c.Y) } } } } func TestAdjustGamma(t *testing.T) { src := image.NewGray(image.Rect(0, 0, 256, 1)) dst := image.NewGray(image.Rect(0, 0, 256, 1)) for i := 0; i <= 255; i++ { src.Pix[i] = uint8(i) } ag := Gamma(2) ag.Draw(dst, src, nil) for i := 100; i <= 150; i++ { if dst.Pix[i] <= src.Pix[i] { t.Errorf("Gamma unexpected color") } } ag = Gamma(0.5) ag.Draw(dst, src, nil) for i := 100; i <= 150; i++ { if dst.Pix[i] >= src.Pix[i] { t.Errorf("Gamma unexpected color") } } ag = Gamma(1) ag.Draw(dst, src, nil) for i := 100; i <= 150; i++ { if dst.Pix[i] != src.Pix[i] { t.Errorf("Gamma unexpected color") } } } func TestContrast(t *testing.T) { testData := []struct { desc string p float32 srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "contrast (0)", 0, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, }, { "contrast (30)", 30, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x00, 0x25, 0x00, 0x25, 0x00, 0x53, 0xC5, 0xAE, 0xC5, 0x53, 0x00, 0x80, 0x00, 0x80, 0x00, }, }, { "contrast (-30)", -30, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x26, 0x53, 0x26, 0x53, 0x26, 0x69, 0xA1, 0x96, 0xA1, 0x69, 0x26, 0x80, 0x26, 0x80, 0x26, }, }, { "contrast (100)", 100, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, }, }, { "contrast (200)", 200, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, }, }, { "contrast (-100)", -100, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, }, }, { "contrast (-200)", -200, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, }, }, } for _, d := range testData { src := image.NewGray(d.srcb) src.Pix = d.srcPix f := Contrast(d.p) dst := image.NewGray(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } } func TestBrightness(t *testing.T) { testData := []struct { desc string p float32 srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "brightness (0)", 0, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, }, { "brightness (30)", 30, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x4D, 0x8D, 0x4D, 0x8D, 0x4D, 0xAD, 0xFD, 0xED, 0xFD, 0xAD, 0x4D, 0xCD, 0x4D, 0xCD, 0x4D, }, }, { "brightness (-30)", -30, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA1, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x64, 0x55, 0x64, 0x14, 0x00, 0x34, 0x00, 0x34, 0x00, }, }, { "brightness (100)", 100, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, }, { "brightness (200)", 200, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }, }, { "brightness (-100)", -100, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, }, { "brightness (-200)", -200, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, }, } for _, d := range testData { src := image.NewGray(d.srcb) src.Pix = d.srcPix f := Brightness(d.p) dst := image.NewGray(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } } func TestSigmoid(t *testing.T) { testData := []struct { desc string midpoint, factor float32 srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "sigmoid (0.5, 0)", 0.5, 0, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, }, { "sigmoid (0.5, 3)", 0.5, 3, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x00, 0x38, 0x00, 0x38, 0x00, 0x5B, 0xB7, 0xA5, 0xB7, 0x5B, 0x00, 0x80, 0x00, 0x80, 0x00, }, }, { "sigmoid (0.5, -3)", 0.5, -3, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x00, 0x48, 0x00, 0x48, 0x00, 0x65, 0xA9, 0x9B, 0xA9, 0x65, 0x00, 0x80, 0x00, 0x80, 0x00, }, }, } for _, d := range testData { src := image.NewGray(d.srcb) src.Pix = d.srcPix f := Sigmoid(d.midpoint, d.factor) dst := image.NewGray(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } } func TestGrayscale(t *testing.T) { testData := []struct { desc string srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "grayscale 0x0", image.Rect(0, 0, 0, 0), image.Rect(0, 0, 0, 0), []uint8{}, []uint8{}, }, { "grayscale 2x3", image.Rect(-1, -1, 1, 2), image.Rect(0, 0, 2, 3), []uint8{ 0x00, 0x10, 0x20, 0x30, 0xFF, 0x00, 0x88, 0xFF, 0xF0, 0xE0, 0xD0, 0xC0, 0x11, 0x66, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, }, []uint8{ 0x0D, 0x0D, 0x0D, 0x30, 0x5C, 0x5C, 0x5C, 0xFF, 0xE3, 0xE3, 0xE3, 0xC0, 0x56, 0x56, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, }, }, } for _, d := range testData { src := image.NewNRGBA(d.srcb) src.Pix = d.srcPix f := Grayscale() dst := image.NewNRGBA(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } } func TestSepia(t *testing.T) { testData := []struct { desc string p float32 srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "sepia 100 0x0", 100, image.Rect(0, 0, 0, 0), image.Rect(0, 0, 0, 0), []uint8{}, []uint8{}, }, { "sepia 0 2x3", 0, image.Rect(-1, -1, 1, 2), image.Rect(0, 0, 2, 3), []uint8{ 0x00, 0x10, 0x20, 0x30, 0xFF, 0x00, 0x88, 0xFF, 0xF0, 0xE0, 0xD0, 0xC0, 0x11, 0x66, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, }, []uint8{ 0x00, 0x10, 0x20, 0x30, 0xFF, 0x00, 0x88, 0xFF, 0xF0, 0xE0, 0xD0, 0xC0, 0x11, 0x66, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, }, }, { "sepia 100 2x3", 100, image.Rect(-1, -1, 1, 2), image.Rect(0, 0, 2, 3), []uint8{ 0x00, 0x10, 0x20, 0x30, 0xFF, 0x00, 0x88, 0xFF, 0xF0, 0xE0, 0xD0, 0xC0, 0x11, 0x66, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, }, []uint8{ 0x12, 0x10, 0x0D, 0x30, 0x7E, 0x70, 0x57, 0xFF, 0xFF, 0xFF, 0xD4, 0xC0, 0x78, 0x6B, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xEF, 0xFF, }, }, } for _, d := range testData { src := image.NewNRGBA(d.srcb) src.Pix = d.srcPix f := Sepia(d.p) dst := image.NewNRGBA(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } } func TestNormalizeHue(t *testing.T) { testData := []struct { h0, h1 float32 }{ {0, 0}, {0.1, 0.1}, {0.5, 0.5}, {0.9, 0.9}, {1.1, 0.1}, {3.0, 0.0}, {5.7, 0.7}, {-0.1, 0.9}, {-0.5, 0.5}, {-0.9, 0.1}, {-3.0, 0.0}, {-5.7, 0.3}, } for _, d := range testData { h := normalizeHue(d.h0) if absf32(h-d.h1) > 0.00001 { t.Errorf("normalizeHue(%#v) failed: %#v expected: %#v", d.h0, h, d.h1) } } } func TestHue(t *testing.T) { testData := []struct { desc string p float32 srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "hue 0 0x0", 0, image.Rect(0, 0, 0, 0), image.Rect(0, 0, 0, 0), []uint8{}, []uint8{}, }, { "hue 0", 0, image.Rect(-1, -1, 1, 3), image.Rect(0, 0, 2, 4), []uint8{ 0x00, 0x10, 0x20, 0x30, 0x99, 0x66, 0x33, 0xFF, 0xF0, 0xE0, 0xD0, 0xC0, 0x11, 0x66, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xEE, 0x50, 0xA0, 0x77, 0xFD, 0xFE, 0xFD, 0xFD, }, []uint8{ 0x00, 0x10, 0x20, 0x30, 0x99, 0x66, 0x33, 0xFF, 0xF0, 0xE0, 0xD0, 0xC0, 0x11, 0x66, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xEE, 0x50, 0xA0, 0x77, 0xFD, 0xFE, 0xFD, 0xFD, }, }, { "hue -720", // same as 0 -720, image.Rect(-1, -1, 1, 3), image.Rect(0, 0, 2, 4), []uint8{ 0x00, 0x10, 0x20, 0x30, 0x99, 0x66, 0x33, 0xFF, 0xF0, 0xE0, 0xD0, 0xC0, 0x11, 0x66, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xEE, 0x50, 0xA0, 0x77, 0xFD, 0xFE, 0xFD, 0xFD, }, []uint8{ 0x00, 0x10, 0x20, 0x30, 0x99, 0x66, 0x33, 0xFF, 0xF0, 0xE0, 0xD0, 0xC0, 0x11, 0x66, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xEE, 0x50, 0xA0, 0x77, 0xFD, 0xFE, 0xFD, 0xFD, }, }, { "hue -90", -90, image.Rect(-1, -1, 1, 3), image.Rect(0, 0, 2, 4), []uint8{ 0x00, 0x10, 0x20, 0x30, 0x99, 0x66, 0x33, 0xFF, 0xF0, 0xE0, 0xD0, 0xC0, 0x11, 0x66, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xEE, 0x50, 0xA0, 0x77, 0xFD, 0xFE, 0xFD, 0xFD, }, []uint8{ 0x00, 0x20, 0x00, 0x30, 0x99, 0x33, 0x99, 0xFF, 0xF0, 0xD0, 0xF0, 0xC0, 0x11, 0xBB, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x50, 0x51, 0xEE, 0x77, 0xFE, 0xFE, 0xFD, 0xFD, }, }, { "hue 630", // same as -90 630, image.Rect(-1, -1, 1, 3), image.Rect(0, 0, 2, 4), []uint8{ 0x00, 0x10, 0x20, 0x30, 0x99, 0x66, 0x33, 0xFF, 0xF0, 0xE0, 0xD0, 0xC0, 0x11, 0x66, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xEE, 0x50, 0xA0, 0x77, 0xFD, 0xFE, 0xFD, 0xFD, }, []uint8{ 0x00, 0x20, 0x00, 0x30, 0x99, 0x33, 0x99, 0xFF, 0xF0, 0xD0, 0xF0, 0xC0, 0x11, 0xBB, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x50, 0x51, 0xEE, 0x77, 0xFE, 0xFE, 0xFD, 0xFD, }, }, { "hue 90", 90, image.Rect(-1, -1, 1, 3), image.Rect(0, 0, 2, 4), []uint8{ 0x00, 0x10, 0x20, 0x30, 0x99, 0x66, 0x33, 0xFF, 0xF0, 0xE0, 0xD0, 0xC0, 0x11, 0x66, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xEE, 0x50, 0xA0, 0x77, 0xFD, 0xFE, 0xFD, 0xFD, }, []uint8{ 0x20, 0x00, 0x20, 0x30, 0x33, 0x99, 0x33, 0xFF, 0xD0, 0xF0, 0xD0, 0xC0, 0xBB, 0x11, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xEE, 0xED, 0x50, 0x77, 0xFD, 0xFE, 0xFE, 0xFD, }, }, { "hue 3690", // same as 90 3690, image.Rect(-1, -1, 1, 3), image.Rect(0, 0, 2, 4), []uint8{ 0x00, 0x10, 0x20, 0x30, 0x99, 0x66, 0x33, 0xFF, 0xF0, 0xE0, 0xD0, 0xC0, 0x11, 0x66, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xEE, 0x50, 0xA0, 0x77, 0xFD, 0xFE, 0xFD, 0xFD, }, []uint8{ 0x20, 0x00, 0x20, 0x30, 0x33, 0x99, 0x33, 0xFF, 0xD0, 0xF0, 0xD0, 0xC0, 0xBB, 0x11, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xEE, 0xED, 0x50, 0x77, 0xFD, 0xFE, 0xFE, 0xFD, }, }, } for _, d := range testData { src := image.NewNRGBA(d.srcb) src.Pix = d.srcPix f := Hue(d.p) dst := image.NewNRGBA(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } } func TestSaturation(t *testing.T) { testData := []struct { desc string p float32 srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "saturation 0 0x0", 0, image.Rect(0, 0, 0, 0), image.Rect(0, 0, 0, 0), []uint8{}, []uint8{}, }, { "saturation 0", 0, image.Rect(-1, -1, 1, 3), image.Rect(0, 0, 2, 4), []uint8{ 0x00, 0x10, 0x20, 0x30, 0x99, 0x66, 0x33, 0xFF, 0xF0, 0xE0, 0xD0, 0xC0, 0x11, 0x66, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x50, 0xA0, 0x77, 0xEE, 0xFE, 0xEE, 0xFD, }, []uint8{ 0x00, 0x10, 0x20, 0x30, 0x99, 0x66, 0x33, 0xFF, 0xF0, 0xE0, 0xD0, 0xC0, 0x11, 0x66, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x50, 0xA0, 0x77, 0xEE, 0xFE, 0xEE, 0xFD, }, }, { "saturation -50", -50, image.Rect(-1, -1, 1, 3), image.Rect(0, 0, 2, 4), []uint8{ 0x00, 0x10, 0x20, 0x30, 0x99, 0x66, 0x33, 0xFF, 0xF0, 0xE0, 0xD0, 0xC0, 0x11, 0x66, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x50, 0xA0, 0x77, 0xEE, 0xFE, 0xEE, 0xFD, }, []uint8{ 0x08, 0x10, 0x18, 0x30, 0x80, 0x66, 0x4D, 0xFF, 0xE8, 0xE0, 0xD8, 0xC0, 0x3B, 0x66, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0x74, 0x9C, 0x77, 0xF2, 0xFA, 0xF2, 0xFD, }, }, { "saturation 100", 100, image.Rect(-1, -1, 1, 3), image.Rect(0, 0, 2, 4), []uint8{ 0x00, 0x10, 0x20, 0x30, 0x99, 0x66, 0x33, 0xFF, 0xF0, 0xE0, 0xD0, 0xC0, 0x11, 0x66, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x50, 0xA0, 0x77, 0xEE, 0xFE, 0xEE, 0xFD, }, []uint8{ 0x00, 0x10, 0x20, 0x30, 0xCC, 0x66, 0x00, 0xFF, 0xFF, 0xE0, 0xC1, 0xC0, 0x00, 0x66, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x31, 0xA3, 0x77, 0xED, 0xFF, 0xED, 0xFD, }, }, } for _, d := range testData { src := image.NewNRGBA(d.srcb) src.Pix = d.srcPix f := Saturation(d.p) dst := image.NewNRGBA(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } } func TestColorize(t *testing.T) { testData := []struct { desc string h, s, p float32 srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "colorize 0, 0, 0, 0x0", 0, 0, 0, image.Rect(0, 0, 0, 0), image.Rect(0, 0, 0, 0), []uint8{}, []uint8{}, }, { "colorize 0, 100, 0", 0, 100, 0, image.Rect(-1, -1, 1, 3), image.Rect(0, 0, 2, 4), []uint8{ 0x00, 0x10, 0x20, 0x30, 0x99, 0x66, 0x33, 0xFF, 0xF0, 0xE0, 0xD0, 0xC0, 0x11, 0x66, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x50, 0xA0, 0x77, 0xEE, 0xFE, 0xEE, 0xFD, }, []uint8{ 0x00, 0x10, 0x20, 0x30, 0x99, 0x66, 0x33, 0xFF, 0xF0, 0xE0, 0xD0, 0xC0, 0x11, 0x66, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x50, 0xA0, 0x77, 0xEE, 0xFE, 0xEE, 0xFD, }, }, { "colorize 0, 100, 100", 0, 100, 100, image.Rect(-1, -1, 1, 3), image.Rect(0, 0, 2, 4), []uint8{ 0x00, 0x10, 0x20, 0x30, 0x99, 0x66, 0x33, 0xFF, 0xF0, 0xE0, 0xD0, 0xC0, 0x11, 0x66, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x50, 0xA0, 0x77, 0xEE, 0xFE, 0xEE, 0xFD, }, []uint8{ 0x20, 0x00, 0x00, 0x30, 0xCC, 0x00, 0x00, 0xFF, 0xFF, 0xC1, 0xC1, 0xC0, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x31, 0x31, 0x77, 0xFF, 0xED, 0xED, 0xFD, }, }, } for _, d := range testData { src := image.NewNRGBA(d.srcb) src.Pix = d.srcPix f := Colorize(d.h, d.s, d.p) dst := image.NewNRGBA(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } } func TestColorBalance(t *testing.T) { testData := []struct { desc string r, g, b float32 srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "color balance 0, 0, 0, 0x0", 0, 0, 0, image.Rect(0, 0, 0, 0), image.Rect(0, 0, 0, 0), []uint8{}, []uint8{}, }, { "color balance 0, 0, 0", 0, 0, 0, image.Rect(-1, -1, 1, 3), image.Rect(0, 0, 2, 4), []uint8{ 0x00, 0x10, 0x20, 0x30, 0x99, 0x66, 0x33, 0xFF, 0xF0, 0xE0, 0xD0, 0xC0, 0x11, 0x66, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x50, 0xA0, 0x77, 0xEE, 0xFE, 0xEE, 0xFD, }, []uint8{ 0x00, 0x10, 0x20, 0x30, 0x99, 0x66, 0x33, 0xFF, 0xF0, 0xE0, 0xD0, 0xC0, 0x11, 0x66, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x50, 0xA0, 0x77, 0xEE, 0xFE, 0xEE, 0xFD, }, }, { "color balance 10, -20, 200", 10, -20, 200, image.Rect(-1, -1, 1, 3), image.Rect(0, 0, 2, 4), []uint8{ 0x00, 0x10, 0x20, 0x30, 0x99, 0x66, 0x33, 0xFF, 0xF0, 0xE0, 0xD0, 0xC0, 0x11, 0x66, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x50, 0xA0, 0x77, 0xEE, 0xFE, 0xEE, 0xFD, }, []uint8{ 0x00, 0x0D, 0x60, 0x30, 0xA8, 0x52, 0x99, 0xFF, 0xFF, 0xB3, 0xFF, 0xC0, 0x13, 0x52, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xCC, 0xFF, 0xFF, 0xF6, 0x40, 0xFF, 0x77, 0xFF, 0xCB, 0xFF, 0xFD, }, }, } for _, d := range testData { src := image.NewNRGBA(d.srcb) src.Pix = d.srcPix f := ColorBalance(d.r, d.g, d.b) dst := image.NewNRGBA(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } } func TestThreshold(t *testing.T) { testData := []struct { desc string percentage float32 srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "threshold -1", -1, image.Rect(-1, -1, 5, 0), image.Rect(0, 0, 6, 1), []uint8{0x00, 0x33, 0x66, 0x99, 0xcc, 0xff}, []uint8{0x00, 0xff, 0xff, 0xff, 0xff, 0xff}, }, { "threshold 0", 0, image.Rect(-1, -1, 5, 0), image.Rect(0, 0, 6, 1), []uint8{0x00, 0x33, 0x66, 0x99, 0xcc, 0xff}, []uint8{0x00, 0xff, 0xff, 0xff, 0xff, 0xff}, }, { "threshold 30", 30, image.Rect(-1, -1, 5, 0), image.Rect(0, 0, 6, 1), []uint8{0x00, 0x33, 0x66, 0x99, 0xcc, 0xff}, []uint8{0x00, 0x00, 0xff, 0xff, 0xff, 0xff}, }, { "threshold 50", 50, image.Rect(-1, -1, 5, 0), image.Rect(0, 0, 6, 1), []uint8{0x00, 0x33, 0x66, 0x99, 0xcc, 0xff}, []uint8{0x00, 0x00, 0x00, 0xff, 0xff, 0xff}, }, { "threshold 90", 90, image.Rect(-1, -1, 5, 0), image.Rect(0, 0, 6, 1), []uint8{0x00, 0x33, 0x66, 0x99, 0xcc, 0xff}, []uint8{0x00, 0x00, 0x00, 0x00, 0x00, 0xff}, }, { "threshold 100", 100, image.Rect(-1, -1, 5, 0), image.Rect(0, 0, 6, 1), []uint8{0x00, 0x33, 0x66, 0x99, 0xcc, 0xff}, []uint8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, }, { "threshold 101", 101, image.Rect(-1, -1, 5, 0), image.Rect(0, 0, 6, 1), []uint8{0x00, 0x33, 0x66, 0x99, 0xcc, 0xff}, []uint8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, }, } for _, d := range testData { src := image.NewGray(d.srcb) src.Pix = d.srcPix f := Threshold(d.percentage) dst := image.NewGray(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } } func TestColorFunc(t *testing.T) { testData := []struct { desc string fn func(r0, g0, b0, a0 float32) (r, g, b, a float32) srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "color func 0x0", func(r0, g0, b0, a0 float32) (r, g, b, a float32) { return r0, g0, b0, a0 }, image.Rect(0, 0, 0, 0), image.Rect(0, 0, 0, 0), []uint8{}, []uint8{}, }, { "color func swap channels", func(r0, g0, b0, a0 float32) (r, g, b, a float32) { return a0, b0, g0, r0 }, image.Rect(-1, -1, 1, 3), image.Rect(0, 0, 2, 4), []uint8{ 0x00, 0x10, 0x20, 0x30, 0x99, 0x66, 0x33, 0xFF, 0xF0, 0xE0, 0xD0, 0xC0, 0x11, 0x66, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x50, 0xA0, 0x77, 0xEE, 0xFE, 0xEE, 0xFD, }, []uint8{ 0x30, 0x20, 0x10, 0x00, 0xFF, 0x33, 0x66, 0x99, 0xC0, 0xD0, 0xE0, 0xF0, 0x00, 0xBB, 0x66, 0x11, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x77, 0xA0, 0x50, 0xE0, 0xFD, 0xEE, 0xFE, 0xEE, }, }, { "color func invert all", func(r0, g0, b0, a0 float32) (r, g, b, a float32) { return 1 - r0, 1 - g0, 1 - b0, 1 - a0 }, image.Rect(-1, -1, 1, 3), image.Rect(0, 0, 2, 4), []uint8{ 0x00, 0x10, 0x20, 0x30, 0x99, 0x66, 0x33, 0xFF, 0xF0, 0xE0, 0xD0, 0xC0, 0x11, 0x66, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x50, 0xA0, 0x77, 0xEE, 0xFE, 0xEE, 0xFD, }, []uint8{ 0xFF, 0xEF, 0xDF, 0xCF, 0x66, 0x99, 0xCC, 0x00, 0x0F, 0x1F, 0x2F, 0x3F, 0xEE, 0x99, 0x44, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xAF, 0x5F, 0x88, 0x11, 0x01, 0x11, 0x02, }, }, } for _, d := range testData { src := image.NewNRGBA(d.srcb) src.Pix = d.srcPix f := ColorFunc(d.fn) dst := image.NewNRGBA(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } } gift-0.2.0/convolution.go000066400000000000000000000326601513354670200153650ustar00rootroot00000000000000package gift import ( "image" "image/draw" "math" ) type uweight struct { u int weight float32 } type uvweight struct { u int v int weight float32 } func prepareConvolutionWeights(kernel []float32, normalize bool) (int, []uvweight) { size := int(math.Sqrt(float64(len(kernel)))) if size%2 == 0 { size-- } if size < 1 { return 0, []uvweight{} } center := size / 2 weights := []uvweight{} for i := 0; i < size; i++ { for j := 0; j < size; j++ { k := j*size + i w := float32(0) if k < len(kernel) { w = kernel[k] } if w != 0 { weights = append(weights, uvweight{u: i - center, v: j - center, weight: w}) } } } if !normalize { return size, weights } var sum, sumpositive float32 for _, w := range weights { sum += w.weight if w.weight > 0 { sumpositive += w.weight } } var div float32 if sum != 0 { div = sum } else if sumpositive != 0 { div = sumpositive } else { return size, weights } for i := 0; i < len(weights); i++ { weights[i].weight /= div } return size, weights } type convolutionFilter struct { kernel []float32 normalize bool alpha bool abs bool delta float32 } func (p *convolutionFilter) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { dstBounds = image.Rect(0, 0, srcBounds.Dx(), srcBounds.Dy()) return } func (p *convolutionFilter) Draw(dst draw.Image, src image.Image, options *Options) { if options == nil { options = &defaultOptions } srcb := src.Bounds() dstb := dst.Bounds() if srcb.Dx() <= 0 || srcb.Dy() <= 0 { return } ksize, weights := prepareConvolutionWeights(p.kernel, p.normalize) kcenter := ksize / 2 if ksize < 1 { copyimage(dst, src, options) return } pixGetter := newPixelGetter(src) pixSetter := newPixelSetter(dst) parallelize(options.Workers, srcb.Min.Y, srcb.Max.Y, func(start, stop int) { // Init temporary rows. starty := start rows := make([][]pixel, ksize) for i := range ksize { rowy := starty + i - kcenter if rowy < srcb.Min.Y { rowy = srcb.Min.Y } else if rowy > srcb.Max.Y-1 { rowy = srcb.Max.Y - 1 } row := make([]pixel, srcb.Dx()) pixGetter.getPixelRow(rowy, &row) rows[i] = row } for y := start; y < stop; y++ { // Calculate dst row. for x := srcb.Min.X; x < srcb.Max.X; x++ { var r, g, b, a float32 for _, w := range weights { wx := x + w.u if wx < srcb.Min.X { wx = srcb.Min.X } else if wx > srcb.Max.X-1 { wx = srcb.Max.X - 1 } rowsx := wx - srcb.Min.X rowsy := kcenter + w.v px := rows[rowsy][rowsx] r += px.r * w.weight g += px.g * w.weight b += px.b * w.weight if p.alpha { a += px.a * w.weight } } if p.abs { r = absf32(r) g = absf32(g) b = absf32(b) if p.alpha { a = absf32(a) } } if p.delta != 0 { r += p.delta g += p.delta b += p.delta if p.alpha { a += p.delta } } if !p.alpha { a = rows[kcenter][x-srcb.Min.X].a } pixSetter.setPixel(dstb.Min.X+x-srcb.Min.X, dstb.Min.Y+y-srcb.Min.Y, pixel{r, g, b, a}) } // Rotate temporary rows. if y < stop-1 { tmprow := rows[0] for i := 0; i < ksize-1; i++ { rows[i] = rows[i+1] } nextrowy := min(y+ksize/2+1, srcb.Max.Y-1) pixGetter.getPixelRow(nextrowy, &tmprow) rows[ksize-1] = tmprow } } }) } // Convolution creates a filter that applies a square convolution kernel to an image. // The length of the kernel slice must be the square of an odd kernel size (e.g. 9 for 3x3 kernel, 25 for 5x5 kernel). // Excessive slice members will be ignored. // If normalize parameter is true, the kernel will be normalized before applying the filter. // If alpha parameter is true, the alpha component of color will be filtered too. // If abs parameter is true, absolute values of color components will be taken after doing calculations. // If delta parameter is not zero, this value will be added to the filtered pixels. // // Example: // // // Apply the emboss filter to an image. // g := gift.New( // gift.Convolution( // []float32{ // -1, -1, 0, // -1, 1, 1, // 0, 1, 1, // }, // false, false, false, 0, // ), // ) // dst := image.NewRGBA(g.Bounds(src.Bounds())) // g.Draw(dst, src) func Convolution(kernel []float32, normalize, alpha, abs bool, delta float32) Filter { return &convolutionFilter{ kernel: kernel, normalize: normalize, alpha: alpha, abs: abs, delta: delta, } } // prepareConvolutionWeights1d prepares pixel weights using a convolution kernel. // Weights equal to 0 are excluded. func prepareConvolutionWeights1d(kernel []float32) (int, []uweight) { size := len(kernel) if size%2 == 0 { size-- } if size < 1 { return 0, []uweight{} } center := size / 2 weights := []uweight{} for i := 0; i < size; i++ { w := float32(0) if i < len(kernel) { w = kernel[i] } if w != 0 { weights = append(weights, uweight{i - center, w}) } } return size, weights } // convolveLine convolves a single line of pixels according to the given weights. func convolveLine(dstBuf []pixel, srcBuf []pixel, weights []uweight) { max := len(srcBuf) - 1 if max < 0 { return } for dstu := range srcBuf { var r, g, b, a float32 for _, w := range weights { k := dstu + w.u if k < 0 { k = 0 } else if k > max { k = max } c := srcBuf[k] wa := c.a * w.weight r += c.r * wa g += c.g * wa b += c.b * wa a += wa } if a != 0 { r /= a g /= a b /= a } dstBuf[dstu] = pixel{r, g, b, a} } } // convolve1dv performs a fast vertical 1d convolution. func convolve1dv(dst draw.Image, src image.Image, kernel []float32, options *Options) { srcb := src.Bounds() dstb := dst.Bounds() if srcb.Dx() <= 0 || srcb.Dy() <= 0 { return } if len(kernel) < 1 { copyimage(dst, src, options) return } _, weights := prepareConvolutionWeights1d(kernel) pixGetter := newPixelGetter(src) pixSetter := newPixelSetter(dst) parallelize(options.Workers, srcb.Min.X, srcb.Max.X, func(start, stop int) { buf := getPixelBuf(srcb.Dy(), srcb.Dy()) defer putPixelBuf(buf) for x := start; x < stop; x++ { pixGetter.getPixelColumn(x, &buf.src) convolveLine(buf.dst, buf.src, weights) pixSetter.setPixelColumn(dstb.Min.X+x-srcb.Min.X, buf.dst) } }) } // convolve1dh performs afast horizontal 1d convolution. func convolve1dh(dst draw.Image, src image.Image, kernel []float32, options *Options) { srcb := src.Bounds() dstb := dst.Bounds() if srcb.Dx() <= 0 || srcb.Dy() <= 0 { return } if len(kernel) < 1 { copyimage(dst, src, options) return } _, weights := prepareConvolutionWeights1d(kernel) pixGetter := newPixelGetter(src) pixSetter := newPixelSetter(dst) parallelize(options.Workers, srcb.Min.Y, srcb.Max.Y, func(start, stop int) { buf := getPixelBuf(srcb.Dx(), srcb.Dx()) defer putPixelBuf(buf) for y := start; y < stop; y++ { pixGetter.getPixelRow(y, &buf.src) convolveLine(buf.dst, buf.src, weights) pixSetter.setPixelRow(dstb.Min.Y+y-srcb.Min.Y, buf.dst) } }) } func gaussianBlurKernel(x, sigma float32) float32 { return float32(math.Exp(-float64(x*x)/float64(2*sigma*sigma)) / (float64(sigma) * math.Sqrt(2*math.Pi))) } type gausssianBlurFilter struct { sigma float32 } func (p *gausssianBlurFilter) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { dstBounds = image.Rect(0, 0, srcBounds.Dx(), srcBounds.Dy()) return } func (p *gausssianBlurFilter) Draw(dst draw.Image, src image.Image, options *Options) { if options == nil { options = &defaultOptions } srcb := src.Bounds() if srcb.Dx() <= 0 || srcb.Dy() <= 0 { return } if p.sigma <= 0 { copyimage(dst, src, options) return } radius := int(math.Ceil(float64(p.sigma * 3))) size := 2*radius + 1 center := radius kernel := make([]float32, size) kernel[center] = gaussianBlurKernel(0, p.sigma) sum := kernel[center] for i := 1; i <= radius; i++ { f := gaussianBlurKernel(float32(i), p.sigma) kernel[center-i] = f kernel[center+i] = f sum += 2 * f } for i := range kernel { kernel[i] /= sum } tmp := createTempImage(srcb) convolve1dh(tmp, src, kernel, options) convolve1dv(dst, tmp, kernel, options) } // GaussianBlur creates a filter that applies a gaussian blur to an image. // The sigma parameter must be positive and indicates how much the image will be blurred. // Blur affected radius roughly equals 3 * sigma. // // Example: // // g := gift.New( // gift.GaussianBlur(1.5), // ) // dst := image.NewRGBA(g.Bounds(src.Bounds())) // g.Draw(dst, src) func GaussianBlur(sigma float32) Filter { return &gausssianBlurFilter{ sigma: sigma, } } type unsharpMaskFilter struct { sigma float32 amount float32 threshold float32 } func (p *unsharpMaskFilter) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { dstBounds = image.Rect(0, 0, srcBounds.Dx(), srcBounds.Dy()) return } func unsharp(orig, blurred, amount, threshold float32) float32 { dif := (orig - blurred) * amount if absf32(dif) > absf32(threshold) { return orig + dif } return orig } func (p *unsharpMaskFilter) Draw(dst draw.Image, src image.Image, options *Options) { if options == nil { options = &defaultOptions } srcb := src.Bounds() dstb := dst.Bounds() if srcb.Dx() <= 0 || srcb.Dy() <= 0 { return } blurred := createTempImage(srcb) blur := GaussianBlur(p.sigma) blur.Draw(blurred, src, options) pixGetterOrig := newPixelGetter(src) pixGetterBlur := newPixelGetter(blurred) pixelSetter := newPixelSetter(dst) parallelize(options.Workers, srcb.Min.Y, srcb.Max.Y, func(start, stop int) { for y := start; y < stop; y++ { for x := srcb.Min.X; x < srcb.Max.X; x++ { pxOrig := pixGetterOrig.getPixel(x, y) pxBlur := pixGetterBlur.getPixel(x, y) r := unsharp(pxOrig.r, pxBlur.r, p.amount, p.threshold) g := unsharp(pxOrig.g, pxBlur.g, p.amount, p.threshold) b := unsharp(pxOrig.b, pxBlur.b, p.amount, p.threshold) a := unsharp(pxOrig.a, pxBlur.a, p.amount, p.threshold) pixelSetter.setPixel(dstb.Min.X+x-srcb.Min.X, dstb.Min.Y+y-srcb.Min.Y, pixel{r, g, b, a}) } } }) } // UnsharpMask creates a filter that sharpens an image. // The sigma parameter is used in a gaussian function and affects the radius of effect. // Sigma must be positive. Sharpen radius roughly equals 3 * sigma. // The amount parameter controls how much darker and how much lighter the edge borders become. Typically between 0.5 and 1.5. // The threshold parameter controls the minimum brightness change that will be sharpened. Typically between 0 and 0.05. // // Example: // // g := gift.New( // gift.UnsharpMask(1, 1, 0), // ) // dst := image.NewRGBA(g.Bounds(src.Bounds())) // g.Draw(dst, src) func UnsharpMask(sigma, amount, threshold float32) Filter { return &unsharpMaskFilter{ sigma: sigma, amount: amount, threshold: threshold, } } type meanFilter struct { ksize int disk bool } func (p *meanFilter) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { dstBounds = image.Rect(0, 0, srcBounds.Dx(), srcBounds.Dy()) return } func (p *meanFilter) Draw(dst draw.Image, src image.Image, options *Options) { if options == nil { options = &defaultOptions } srcb := src.Bounds() if srcb.Dx() <= 0 || srcb.Dy() <= 0 { return } ksize := p.ksize if ksize%2 == 0 { ksize-- } if ksize <= 1 { copyimage(dst, src, options) return } if p.disk { diskKernel := genDisk(p.ksize) f := Convolution(diskKernel, true, true, false, 0) f.Draw(dst, src, options) } else { kernel := make([]float32, ksize*ksize) for i := range kernel { kernel[i] = 1 } f := Convolution(kernel, true, true, false, 0) f.Draw(dst, src, options) } } // Mean creates a local mean image filter. // Takes an average across a neighborhood for each pixel. // The ksize parameter is the kernel size. It must be an odd positive integer (for example: 3, 5, 7). // If the disk parameter is true, a disk-shaped neighborhood will be used instead of a square neighborhood. func Mean(ksize int, disk bool) Filter { return &meanFilter{ ksize: ksize, disk: disk, } } type hvConvolutionFilter struct { hkernel, vkernel []float32 } func (p *hvConvolutionFilter) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { dstBounds = image.Rect(0, 0, srcBounds.Dx(), srcBounds.Dy()) return } func (p *hvConvolutionFilter) Draw(dst draw.Image, src image.Image, options *Options) { if options == nil { options = &defaultOptions } srcb := src.Bounds() dstb := dst.Bounds() if srcb.Dx() <= 0 || srcb.Dy() <= 0 { return } tmph := createTempImage(srcb) Convolution(p.hkernel, false, false, true, 0).Draw(tmph, src, options) pixGetterH := newPixelGetter(tmph) tmpv := createTempImage(srcb) Convolution(p.vkernel, false, false, true, 0).Draw(tmpv, src, options) pixGetterV := newPixelGetter(tmpv) pixSetter := newPixelSetter(dst) parallelize(options.Workers, srcb.Min.Y, srcb.Max.Y, func(start, stop int) { for y := start; y < stop; y++ { for x := srcb.Min.X; x < srcb.Max.X; x++ { pxh := pixGetterH.getPixel(x, y) pxv := pixGetterV.getPixel(x, y) r := sqrtf32(pxh.r*pxh.r + pxv.r*pxv.r) g := sqrtf32(pxh.g*pxh.g + pxv.g*pxv.g) b := sqrtf32(pxh.b*pxh.b + pxv.b*pxv.b) pixSetter.setPixel(dstb.Min.X+x-srcb.Min.X, dstb.Min.Y+y-srcb.Min.Y, pixel{r, g, b, pxh.a}) } } }) } // Sobel creates a filter that applies a sobel operator to an image. func Sobel() Filter { return &hvConvolutionFilter{ hkernel: []float32{-1, 0, 1, -2, 0, 2, -1, 0, 1}, vkernel: []float32{-1, -2, -1, 0, 0, 0, 1, 2, 1}, } } gift-0.2.0/convolution_test.go000066400000000000000000000353111513354670200164200ustar00rootroot00000000000000package gift import ( "image" "testing" ) func TestConvolution(t *testing.T) { testData := []struct { desc string kernel []float32 normalize, alpha, abs bool delta float32 srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "convolution (0x0, false, false, false, 0)", []float32{}, false, false, false, 0, image.Rect(-1, -1, 2, 2), image.Rect(0, 0, 3, 3), []uint8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, []uint8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, }, { "convolution (3x3, false, false, false, 0)", []float32{ 0, 0, 1, 0, 0, 0, 1, 0, 0, }, false, false, false, 0, image.Rect(-1, -1, 2, 2), image.Rect(0, 0, 3, 3), []uint8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, []uint8{ 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0x60, 0x00, 0x20, 0x40, 0x60, 0x80, 0x80, 0x60, 0x40, 0x00, 0xA0, 0xA0, 0xA0, 0x00, 0x20, 0x40, 0x60, 0x00, 0x80, 0x60, 0x40, 0x20, 0x80, 0x60, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, }, }, { "convolution (3x3, true, false, false, 0)", []float32{ 0, 0, 1, 0, 0, 0, 1, 0, 0, }, true, false, false, 0, image.Rect(-1, -1, 2, 2), image.Rect(0, 0, 3, 3), []uint8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, []uint8{ 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0x10, 0x20, 0x30, 0x80, 0x40, 0x30, 0x20, 0x00, 0x50, 0x50, 0x50, 0x00, 0x10, 0x20, 0x30, 0x00, 0x40, 0x30, 0x20, 0x20, 0x40, 0x30, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, }, }, { "convolution (3x3, false, true, false, 0)", []float32{ 0, 0, 1, 0, 0, 0, 1, 0, 0, }, false, true, false, 0, image.Rect(-1, -1, 2, 2), image.Rect(0, 0, 3, 3), []uint8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, []uint8{ 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0x60, 0x80, 0x20, 0x40, 0x60, 0x80, 0x80, 0x60, 0x40, 0x20, 0xA0, 0xA0, 0xA0, 0xA0, 0x20, 0x40, 0x60, 0x80, 0x80, 0x60, 0x40, 0x20, 0x80, 0x60, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, }, }, { "convolution (3x3, true, true, true, 0)", []float32{ 0, 0, 0, -0.5, 0, 0.5, 0, 0, 0, }, true, true, true, 0, image.Rect(-1, -1, 2, 2), image.Rect(0, 0, 3, 3), []uint8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0x60, 0x80, 0x80, 0x60, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0x60, 0x80, 0x80, 0x60, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, []uint8{ 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0x60, 0x80, 0x20, 0x40, 0x60, 0x80, 0x80, 0x60, 0x40, 0x20, 0x60, 0x20, 0x20, 0x60, 0x20, 0x40, 0x60, 0x80, 0x80, 0x60, 0x40, 0x20, 0x80, 0x60, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, }, }, { "convolution (3x3, false, true, false, 3 / 255.0)", []float32{ 0, 0, 1, 0, 0, 0, 1, 0, 0, }, false, true, false, 3 / 255.0, image.Rect(-1, -1, 2, 2), image.Rect(0, 0, 3, 3), []uint8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, []uint8{ 0x03, 0x03, 0x03, 0x03, 0x23, 0x43, 0x63, 0x83, 0x23, 0x43, 0x63, 0x83, 0x83, 0x63, 0x43, 0x23, 0xA3, 0xA3, 0xA3, 0xA3, 0x23, 0x43, 0x63, 0x83, 0x83, 0x63, 0x43, 0x23, 0x83, 0x63, 0x43, 0x23, 0x03, 0x03, 0x03, 0x03, }, }, { "convolution (3x3, false, false, true, 0)", []float32{ 0, 0, -0.5, 0, 0, 0, 0, 0, 0, }, false, false, true, 0, image.Rect(-1, -1, 2, 2), image.Rect(0, 0, 3, 3), []uint8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, []uint8{ 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0x10, 0x20, 0x30, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0x10, 0x20, 0x30, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, }, { "convolution (7x7, false, true, false, 0)", []float32{ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, }, false, true, false, 0, image.Rect(-1, -1, 2, 2), image.Rect(0, 0, 3, 3), []uint8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, []uint8{ 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, }, }, } for _, d := range testData { for _, workers := range []int{5, 1} { src := image.NewNRGBA(d.srcb) src.Pix = d.srcPix f := Convolution(d.kernel, d.normalize, d.alpha, d.abs, d.delta) dst := image.NewNRGBA(f.Bounds(src.Bounds())) f.Draw(dst, src, &Options{Workers: workers}) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } } testKernelSizes := []struct { klen, size int }{ {0, 0}, {1, 1}, {3, 1}, {8, 1}, {9, 3}, {16, 3}, {24, 3}, {25, 5}, {40, 5}, {48, 5}, } for _, d := range testKernelSizes { tmp := make([]float32, d.klen) sz, _ := prepareConvolutionWeights(tmp, true) if sz != d.size { t.Errorf("unexpected kernel size: %d %d", d.klen, sz) } } // check no panics Convolution([]float32{}, true, true, true, 1).Draw(image.NewGray(image.Rect(0, 0, 0, 0)), image.NewGray(image.Rect(0, 0, 0, 0)), nil) convolve1dh(image.NewGray(image.Rect(0, 0, 1, 1)), image.NewGray(image.Rect(0, 0, 1, 1)), []float32{}, nil) convolve1dv(image.NewGray(image.Rect(0, 0, 1, 1)), image.NewGray(image.Rect(0, 0, 1, 1)), []float32{}, nil) convolve1dh(image.NewGray(image.Rect(0, 0, 0, 0)), image.NewGray(image.Rect(0, 0, 0, 0)), []float32{}, nil) convolve1dv(image.NewGray(image.Rect(0, 0, 0, 0)), image.NewGray(image.Rect(0, 0, 0, 0)), []float32{}, nil) convolveLine([]pixel{}, []pixel{}, []uweight{}) prepareConvolutionWeights1d([]float32{0, 0}) prepareConvolutionWeights1d([]float32{}) } func TestGaussianBlur(t *testing.T) { testData := []struct { desc string sigma float32 srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "blur (0)", 0, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, []uint8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, }, { "blur (0.3)", 0.3, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, []uint8{ 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xBD, 0x01, 0xBD, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, }, }, { "blur (1)", 1, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, []uint8{ 0x0B, 0x15, 0x16, 0x15, 0x0B, 0x13, 0x23, 0x25, 0x23, 0x13, 0x0B, 0x15, 0x16, 0x15, 0x0B, }, }, { "blur (3)", 3, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, []uint8{ 0x05, 0x06, 0x06, 0x06, 0x05, 0x05, 0x06, 0x06, 0x06, 0x05, 0x05, 0x06, 0x06, 0x06, 0x05, }, }, } for _, d := range testData { src := image.NewGray(d.srcb) src.Pix = d.srcPix f := GaussianBlur(d.sigma) dst := image.NewGray(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } // check no panics GaussianBlur(0.5).Draw(image.NewGray(image.Rect(0, 0, 0, 0)), image.NewGray(image.Rect(0, 0, 0, 0)), nil) } func TestUnsharpMask(t *testing.T) { testData := []struct { desc string sigma, amount, threshold float32 srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "unsharp mask (0.3, 1, 0)", 0.3, 1, 0, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB1, 0xA1, 0xB1, 0x60, 0x00, 0x81, 0x00, 0x81, 0x00, }, }, { "unsharp mask (1, 1, 0)", 1, 1, 0, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x00, 0x45, 0x00, 0x45, 0x00, 0x82, 0xFF, 0xE4, 0xFF, 0x82, 0x00, 0xB2, 0x00, 0xB2, 0x00, }, }, { "unsharp mask (1, 0.5, 0)", 1, 0.5, 0, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x00, 0x42, 0x00, 0x42, 0x00, 0x71, 0xDD, 0xC2, 0xDD, 0x71, 0x00, 0x99, 0x00, 0x99, 0x00, }, }, { "unsharp mask (1, 1, 0.05)", 1, 1, 0.05, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x82, 0xFF, 0xE4, 0xFF, 0x82, 0x00, 0xB2, 0x00, 0xB2, 0x00, }, }, } for _, d := range testData { src := image.NewGray(d.srcb) src.Pix = d.srcPix f := UnsharpMask(d.sigma, d.amount, d.threshold) dst := image.NewGray(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } // check no panics UnsharpMask(0.5, 1, 0).Draw(image.NewGray(image.Rect(0, 0, 0, 0)), image.NewGray(image.Rect(0, 0, 0, 0)), nil) } func TestMean(t *testing.T) { testData := []struct { desc string ksize int disk bool srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "mean (0x0 false)", 0, false, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, }, { "mean (1x1 false)", 1, false, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, }, { "mean (2x2 true)", 2, true, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, }, { "mean (3x3 false)", 3, false, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x10, 0x40, 0x00, 0x40, 0x10, 0x20, 0x50, 0x00, 0x50, 0x20, 0x30, 0x60, 0x00, 0x60, 0x30, }, []uint8{ 0x25, 0x1E, 0x2E, 0x1E, 0x25, 0x30, 0x25, 0x35, 0x25, 0x30, 0x3B, 0x2C, 0x3C, 0x2C, 0x3B, }, }, { "mean (3x3 true)", 3, true, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x10, 0x40, 0x00, 0x40, 0x10, 0x20, 0x50, 0x00, 0x50, 0x20, 0x30, 0x60, 0x00, 0x60, 0x30, }, []uint8{ 0x1D, 0x2D, 0x1A, 0x2D, 0x1D, 0x2A, 0x36, 0x20, 0x36, 0x2A, 0x36, 0x40, 0x26, 0x40, 0x36, }, }, } for _, d := range testData { src := image.NewGray(d.srcb) src.Pix = d.srcPix f := Mean(d.ksize, d.disk) dst := image.NewGray(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } // check no panics Mean(5, false).Draw(image.NewGray(image.Rect(0, 0, 0, 0)), image.NewGray(image.Rect(0, 0, 0, 0)), nil) } func TestSobel(t *testing.T) { testData := []struct { desc string srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "sobel 0x0", image.Rect(0, 0, 0, 0), image.Rect(0, 0, 0, 0), []uint8{}, []uint8{}, }, { "sobel 6x6", image.Rect(-1, -1, 5, 5), image.Rect(0, 0, 6, 6), []uint8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x99, 0x99, 0x99, 0x00, 0x00, 0x99, 0x99, 0x99, 0x99, 0x00, 0x00, 0x99, 0x99, 0x99, 0x99, 0x00, 0x00, 0x99, 0x99, 0x99, 0x99, }, []uint8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, }, }, } for _, d := range testData { src := image.NewGray(d.srcb) src.Pix = d.srcPix f := Sobel() dst := image.NewGray(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } } gift-0.2.0/effects.go000066400000000000000000000036101513354670200144160ustar00rootroot00000000000000package gift import ( "image" "image/draw" ) type pixelateFilter struct { size int } func (p *pixelateFilter) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { dstBounds = image.Rect(0, 0, srcBounds.Dx(), srcBounds.Dy()) return } func (p *pixelateFilter) Draw(dst draw.Image, src image.Image, options *Options) { if options == nil { options = &defaultOptions } blockSize := p.size if blockSize <= 1 { copyimage(dst, src, options) return } srcb := src.Bounds() dstb := dst.Bounds() numBlocksX := srcb.Dx() / blockSize if srcb.Dx()%blockSize > 0 { numBlocksX++ } numBlocksY := srcb.Dy() / blockSize if srcb.Dy()%blockSize > 0 { numBlocksY++ } pixGetter := newPixelGetter(src) pixSetter := newPixelSetter(dst) parallelize(options.Workers, 0, numBlocksY, func(start, stop int) { for by := start; by < stop; by++ { for bx := 0; bx < numBlocksX; bx++ { // Calculate the block bounds. bb := image.Rect(bx*blockSize, by*blockSize, (bx+1)*blockSize, (by+1)*blockSize) bbSrc := bb.Add(srcb.Min).Intersect(srcb) bbDst := bbSrc.Sub(srcb.Min).Add(dstb.Min).Intersect(dstb) // Calculate the average color of the block. var r, g, b, a float32 var cnt float32 for y := bbSrc.Min.Y; y < bbSrc.Max.Y; y++ { for x := bbSrc.Min.X; x < bbSrc.Max.X; x++ { px := pixGetter.getPixel(x, y) r += px.r g += px.g b += px.b a += px.a cnt++ } } if cnt > 0 { r /= cnt g /= cnt b /= cnt a /= cnt } // Set the calculated color for all pixels in the block. for y := bbDst.Min.Y; y < bbDst.Max.Y; y++ { for x := bbDst.Min.X; x < bbDst.Max.X; x++ { pixSetter.setPixel(x, y, pixel{r, g, b, a}) } } } } }) } // Pixelate creates a filter that applies a pixelation effect to an image. func Pixelate(size int) Filter { return &pixelateFilter{ size: size, } } gift-0.2.0/effects_test.go000066400000000000000000000044131513354670200154570ustar00rootroot00000000000000package gift import ( "image" "testing" ) func TestPixelate(t *testing.T) { testData := []struct { desc string size int srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "pixelate (0)", 0, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, }, { "pixelate (1)", 1, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, }, { "pixelate (2)", 2, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x54, 0x54, 0x64, 0x64, 0x30, 0x54, 0x54, 0x64, 0x64, 0x30, 0x40, 0x40, 0x40, 0x40, 0x00, }, }, { "pixelate (3)", 3, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x45, 0x45, 0x45, 0x4d, 0x4d, 0x45, 0x45, 0x45, 0x4d, 0x4d, 0x45, 0x45, 0x45, 0x4d, 0x4d, }, }, { "pixelate (10)", 10, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, }, }, { "pixelate 0x0", 3, image.Rect(-1, -1, -1, -1), image.Rect(0, 0, 0, 0), []uint8{}, []uint8{}, }, } for _, d := range testData { src := image.NewGray(d.srcb) src.Pix = d.srcPix f := Pixelate(d.size) dst := image.NewGray(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } } gift-0.2.0/gift.go000066400000000000000000000130731513354670200137340ustar00rootroot00000000000000/* Package gift provides a set of useful image processing filters. Basic usage: // 1. Create a new filter list and add some filters. g := gift.New( gift.Resize(800, 0, gift.LanczosResampling), gift.UnsharpMask(1, 1, 0), ) // 2. Create a new image of the corresponding size. // dst is a new target image, src is the original image. dst := image.NewRGBA(g.Bounds(src.Bounds())) // 3. Use the Draw func to apply the filters to src and store the result in dst. g.Draw(dst, src) */ package gift import ( "image" "image/draw" "runtime" ) // Filter is an image processing filter. type Filter interface { // Draw applies the filter to the src image and outputs the result to the dst image. Draw(dst draw.Image, src image.Image, options *Options) // Bounds calculates the appropriate bounds of an image after applying the filter. Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) } // Options is the parameters passed to image processing filters. type Options struct { Workers int } func (o *Options) init() { if o.Workers < 1 { // Values from benchmarking on a MacBook M1 with 10 logical CPUs. o.Workers = min(6, runtime.NumCPU()) } } var defaultOptions = Options{} func init() { defaultOptions.init() } // GIFT is a list of image processing filters. type GIFT struct { filters []Filter options Options } // New creates a new filter list and initializes it with the given slice of filters. func New(filters ...Filter) *GIFT { return &GIFT{ filters: filters, options: defaultOptions, } } // NewWithOptions creates a new filter list with the given options and initializes it with the given slice of filters. func NewWithOptions(options Options, filters ...Filter) *GIFT { options.init() return &GIFT{ filters: filters, options: options, } } // Bounds calculates the appropriate bounds for the result image after applying all the added filters. // Parameter srcBounds is the bounds of the source image. // // Example: // // src := image.NewRGBA(image.Rect(0, 0, 100, 200)) // g := gift.New(gift.Rotate90()) // // // calculate image bounds after applying rotation and create a new image of that size. // dst := image.NewRGBA(g.Bounds(src.Bounds())) // dst bounds: (0, 0, 200, 100) func (g *GIFT) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { b := srcBounds for _, f := range g.filters { b = f.Bounds(b) } dstBounds = b return } // Draw applies all the added filters to the src image and outputs the result to the dst image. func (g *GIFT) Draw(dst draw.Image, src image.Image) error { if len(g.filters) == 0 { copyimage(dst, src, &g.options) return nil } first, last := 0, len(g.filters)-1 var tmpIn image.Image var tmpOut draw.Image for i, f := range g.filters { if i == first { tmpIn = src } else { tmpIn = tmpOut } if i == last { tmpOut = dst } else { tmpOut = createTempImage(f.Bounds(tmpIn.Bounds())) } f.Draw(tmpOut, tmpIn, &g.options) } return nil } // Operator is an image composition operator. type Operator int // Composition operators. const ( CopyOperator Operator = iota OverOperator ) // DrawAt applies all the added filters to the src image and outputs the result to the dst image // at the specified position pt using the specified composition operator op. func (g *GIFT) DrawAt(dst draw.Image, src image.Image, pt image.Point, op Operator) error { switch op { case OverOperator: tb := g.Bounds(src.Bounds()) tb = tb.Sub(tb.Min).Add(pt) tmp := createTempImage(tb) if err := g.Draw(tmp, src); err != nil { return err } pixGetterDst := newPixelGetter(dst) pixGetterTmp := newPixelGetter(tmp) pixSetterDst := newPixelSetter(dst) ib := tb.Intersect(dst.Bounds()) parallelize(g.options.Workers, ib.Min.Y, ib.Max.Y, func(start, stop int) { for y := start; y < stop; y++ { for x := ib.Min.X; x < ib.Max.X; x++ { px0 := pixGetterDst.getPixel(x, y) px1 := pixGetterTmp.getPixel(x, y) c1 := px1.a c0 := (1 - c1) * px0.a cs := c0 + c1 c0 /= cs c1 /= cs r := px0.r*c0 + px1.r*c1 g := px0.g*c0 + px1.g*c1 b := px0.b*c0 + px1.b*c1 a := px0.a + px1.a*(1-px0.a) pixSetterDst.setPixel(x, y, pixel{r, g, b, a}) } } }) default: if pt.Eq(dst.Bounds().Min) { return g.Draw(dst, src) } if subimg, ok := getSubImage(dst, pt); ok { return g.Draw(subimg, src) } tb := g.Bounds(src.Bounds()) tb = tb.Sub(tb.Min).Add(pt) tmp := createTempImage(tb) if err := g.Draw(tmp, src); err != nil { return err } pixGetter := newPixelGetter(tmp) pixSetter := newPixelSetter(dst) ib := tb.Intersect(dst.Bounds()) parallelize(g.options.Workers, ib.Min.Y, ib.Max.Y, func(start, stop int) { for y := start; y < stop; y++ { for x := ib.Min.X; x < ib.Max.X; x++ { pixSetter.setPixel(x, y, pixGetter.getPixel(x, y)) } } }) } return nil } func getSubImage(img draw.Image, pt image.Point) (draw.Image, bool) { if !pt.In(img.Bounds()) { return nil, false } switch img := img.(type) { case *image.Gray: return img.SubImage(image.Rectangle{pt, img.Bounds().Max}).(draw.Image), true case *image.Gray16: return img.SubImage(image.Rectangle{pt, img.Bounds().Max}).(draw.Image), true case *image.RGBA: return img.SubImage(image.Rectangle{pt, img.Bounds().Max}).(draw.Image), true case *image.RGBA64: return img.SubImage(image.Rectangle{pt, img.Bounds().Max}).(draw.Image), true case *image.NRGBA: return img.SubImage(image.Rectangle{pt, img.Bounds().Max}).(draw.Image), true case *image.NRGBA64: return img.SubImage(image.Rectangle{pt, img.Bounds().Max}).(draw.Image), true default: return nil, false } } gift-0.2.0/gift_test.go000066400000000000000000000455571513354670200150070ustar00rootroot00000000000000package gift import ( "image" "image/color" "image/draw" _ "image/jpeg" _ "image/png" "os" "runtime" "testing" ) type testFilter struct { z int } func (p *testFilter) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { dstBounds = image.Rect(0, 0, srcBounds.Dx()+p.z, srcBounds.Dy()+p.z*2) return } func (p *testFilter) Draw(dst draw.Image, src image.Image, options *Options) { dst.Set(dst.Bounds().Min.X, dst.Bounds().Min.Y, color.Gray{123}) } func TestGIFT(t *testing.T) { g := New() if g.options.Workers != defaultOptions.Workers { t.Error("unexpected parallelization property") } g = New( &testFilter{1}, &testFilter{2}, &testFilter{3}, ) if len(g.filters) != 3 { t.Error("unexpected filters count") } g = &GIFT{} src := image.NewGray(image.Rect(-1, -1, 1, 1)) src.Pix = []uint8{ 1, 2, 3, 4, } dst := image.NewGray(g.Bounds(src.Bounds())) g.Draw(dst, src) if !dst.Bounds().Size().Eq(src.Bounds().Size()) { t.Error("unexpected dst bounds") } for i := range dst.Pix { if dst.Pix[i] != src.Pix[i] { t.Error("unexpected dst pix") } } } func TestDrawAt(t *testing.T) { testDataGray := []struct { desc string filters []Filter pt image.Point op Operator srcb, dstb image.Rectangle srcPix, dstPix0, dstPix1 []uint8 }{ { "draw at (Gray, [], -2, -2, copy)", []Filter{}, image.Pt(-2, -2), CopyOperator, image.Rect(-1, -1, 2, 2), image.Rect(-2, -2, 2, 2), []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9}, []uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, []uint8{1, 2, 3, 0, 4, 5, 6, 0, 7, 8, 9, 0, 0, 0, 0, 0}, }, { "draw at (Gray, [], -1, -1, copy)", []Filter{}, image.Pt(-1, -1), CopyOperator, image.Rect(-1, -1, 2, 2), image.Rect(-2, -2, 2, 2), []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9}, []uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, []uint8{0, 0, 0, 0, 0, 1, 2, 3, 0, 4, 5, 6, 0, 7, 8, 9}, }, { "draw at (Gray, [], 0, 0, copy)", []Filter{}, image.Pt(0, 0), CopyOperator, image.Rect(-1, -1, 2, 2), image.Rect(-2, -2, 2, 2), []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9}, []uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, []uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 4, 5}, }, { "draw at (Gray, [], 2, 2, copy)", []Filter{}, image.Pt(2, 2), CopyOperator, image.Rect(-1, -1, 2, 2), image.Rect(-2, -2, 2, 2), []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9}, []uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, []uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, }, { "draw at (Gray, [], 0, -10, copy)", []Filter{}, image.Pt(0, -10), CopyOperator, image.Rect(-1, -1, 2, 2), image.Rect(-2, -2, 2, 2), []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9}, []uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, []uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, }, { "draw at (Gray, [], -3, -3, copy)", []Filter{}, image.Pt(-3, -3), CopyOperator, image.Rect(-1, -1, 2, 2), image.Rect(-2, -2, 2, 2), []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9}, []uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, []uint8{5, 6, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, }, { "draw at (Gray, [], -3, -3, over)", []Filter{}, image.Pt(-3, -3), OverOperator, image.Rect(-1, -1, 2, 2), image.Rect(-2, -2, 2, 2), []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9}, []uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, []uint8{5, 6, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, }, { "draw at (Gray, [Resize], -2, -2, copy)", []Filter{Resize(6, 6, NearestNeighborResampling)}, image.Pt(-2, -2), CopyOperator, image.Rect(-1, -1, 2, 2), image.Rect(-2, -2, 2, 2), []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9}, []uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, []uint8{1, 1, 2, 2, 1, 1, 2, 2, 4, 4, 5, 5, 4, 4, 5, 5}, }, { "draw at (Gray, [Resize], -3, -3, copy)", []Filter{Resize(6, 6, NearestNeighborResampling)}, image.Pt(-3, -3), CopyOperator, image.Rect(-1, -1, 2, 2), image.Rect(-2, -2, 2, 2), []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9}, []uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, []uint8{1, 2, 2, 3, 4, 5, 5, 6, 4, 5, 5, 6, 7, 8, 8, 9}, }, { "draw at (Gray, [Resize], -1, -1, copy)", []Filter{Resize(6, 6, NearestNeighborResampling)}, image.Pt(-1, -1), CopyOperator, image.Rect(-1, -1, 2, 2), image.Rect(-2, -2, 2, 2), []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9}, []uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, []uint8{0, 0, 0, 0, 0, 1, 1, 2, 0, 1, 1, 2, 0, 4, 4, 5}, }, { "draw at (Gray, [Resize], -1, -1, copy, empty)", []Filter{Resize(6, 6, NearestNeighborResampling)}, image.Pt(-1, -1), CopyOperator, image.Rect(0, 0, 0, 0), image.Rect(0, 0, 0, 0), []uint8{}, []uint8{}, []uint8{}, }, } for _, d := range testDataGray { src := image.NewGray(d.srcb) src.Pix = d.srcPix g := New(d.filters...) dst := image.NewGray(d.dstb) dst.Pix = d.dstPix0 if err := g.DrawAt(dst, src, d.pt, d.op); err != nil { t.Errorf("test [%s] failed: unexpected error: %v", d.desc, err) } if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix1) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } testDataNRGBA := []struct { desc string filters []Filter pt image.Point op Operator srcb, dstb image.Rectangle srcPix, dstPix0, dstPix1 []uint8 }{ { "draw at (NRGBA, [], 1, 1, over, 0% 100% alpha)", []Filter{}, image.Pt(1, 1), OverOperator, image.Rect(0, 0, 2, 2), image.Rect(0, 0, 3, 3), []uint8{ 10, 20, 30, 255, 40, 50, 60, 255, 100, 200, 0, 255, 0, 250, 200, 255, }, []uint8{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, []uint8{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 20, 30, 255, 40, 50, 60, 255, 0, 0, 0, 0, 100, 200, 0, 255, 0, 250, 200, 255, }, }, { "draw at (NRGBA, [], 1, 1, over, 0% 50% alpha)", []Filter{}, image.Pt(1, 1), OverOperator, image.Rect(0, 0, 2, 2), image.Rect(0, 0, 3, 3), []uint8{ 10, 20, 30, 127, 40, 50, 60, 127, 100, 200, 0, 127, 0, 250, 200, 127, }, []uint8{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, []uint8{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 20, 30, 127, 40, 50, 60, 127, 0, 0, 0, 0, 100, 200, 0, 127, 0, 250, 200, 127, }, }, { "draw at (NRGBA, [], 1, 1, over, 100% 50% alpha)", []Filter{}, image.Pt(1, 1), OverOperator, image.Rect(0, 0, 2, 2), image.Rect(0, 0, 3, 3), []uint8{ 10, 20, 30, 128, 40, 50, 60, 128, 100, 200, 0, 128, 0, 250, 200, 128, }, []uint8{ 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, }, []uint8{ 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 5, 10, 15, 255, 20, 25, 30, 255, 0, 0, 0, 255, 50, 100, 0, 255, 0, 125, 100, 255, }, }, { "draw at (NRGBA, [], 1, 1, over, 100% 25% alpha)", []Filter{}, image.Pt(1, 1), OverOperator, image.Rect(0, 0, 2, 2), image.Rect(0, 0, 3, 3), []uint8{ 20, 40, 80, 64, 40, 80, 120, 64, 100, 200, 0, 64, 0, 100, 200, 64, }, []uint8{ 0, 0, 0, 255, 1, 2, 3, 255, 0, 0, 0, 255, 0, 0, 0, 255, 40, 80, 120, 255, 40, 40, 40, 255, 0, 0, 0, 255, 200, 200, 12, 255, 0, 0, 0, 255, }, []uint8{ 0, 0, 0, 255, 1, 2, 3, 255, 0, 0, 0, 255, 0, 0, 0, 255, 35, 70, 110, 255, 40, 50, 60, 255, 0, 0, 0, 255, 175, 200, 9, 255, 0, 25, 50, 255, }, }, { "draw at (NRGBA, [], 1, 1, over, shape)", []Filter{}, image.Pt(1, 1), OverOperator, image.Rect(0, 0, 2, 2), image.Rect(0, 0, 3, 3), []uint8{ 100, 100, 100, 255, 100, 100, 100, 255, 100, 100, 100, 255, 100, 100, 100, 0, }, []uint8{ 10, 10, 10, 255, 10, 10, 10, 255, 10, 10, 10, 255, 10, 10, 10, 255, 10, 10, 10, 255, 10, 10, 10, 255, 10, 10, 10, 255, 10, 10, 10, 255, 10, 10, 10, 255, }, []uint8{ 10, 10, 10, 255, 10, 10, 10, 255, 10, 10, 10, 255, 10, 10, 10, 255, 100, 100, 100, 255, 100, 100, 100, 255, 10, 10, 10, 255, 100, 100, 100, 255, 10, 10, 10, 255, }, }, } for _, d := range testDataNRGBA { src := image.NewNRGBA(d.srcb) src.Pix = d.srcPix g := New(d.filters...) dst := image.NewNRGBA(d.dstb) dst.Pix = d.dstPix0 if err := g.DrawAt(dst, src, d.pt, d.op); err != nil { t.Errorf("test [%s] failed: unexpected error: %v", d.desc, err) } if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix1) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } } type fakeDrawImage struct { r image.Rectangle } func (p fakeDrawImage) Bounds() image.Rectangle { return p.r } func (p fakeDrawImage) At(x, y int) color.Color { return color.NRGBA{0, 0, 0, 0} } func (p fakeDrawImage) ColorModel() color.Model { return color.NRGBAModel } func (p fakeDrawImage) Set(x, y int, c color.Color) {} func TestSubImage(t *testing.T) { testData := []struct { desc string img draw.Image ok bool }{ { "sub image (Gray)", image.NewGray(image.Rect(0, 0, 10, 10)), true, }, { "sub image (Gray16)", image.NewGray16(image.Rect(0, 0, 10, 10)), true, }, { "sub image (RGBA)", image.NewRGBA(image.Rect(0, 0, 10, 10)), true, }, { "sub image (RGBA64)", image.NewRGBA64(image.Rect(0, 0, 10, 10)), true, }, { "sub image (NRGBA)", image.NewNRGBA(image.Rect(0, 0, 10, 10)), true, }, { "sub image (NRGBA64)", image.NewNRGBA64(image.Rect(0, 0, 10, 10)), true, }, { "sub image (fake)", fakeDrawImage{image.Rect(0, 0, 10, 10)}, false, }, } for _, d := range testData { simg, ok := getSubImage(d.img, image.Pt(3, 3)) if ok != d.ok { t.Errorf("test [%s] failed: expected %#v, got %#v", d.desc, d.ok, ok) } else if ok { simg.Set(5, 5, color.NRGBA{255, 255, 255, 255}) r, g, b, a := d.img.At(5, 5).RGBA() if r != 0xffff || g != 0xffff || b != 0xffff || a != 0xffff { t.Errorf("test [%s] failed: expected (0xffff, 0xffff, 0xffff, 0xffff), got (%d, %d, %d, %d)", d.desc, r, g, b, a) } } } } func TestDraw(t *testing.T) { filters := [][]Filter{ {}, {Resize(2, 2, NearestNeighborResampling), Crop(image.Rect(0, 0, 1, 1))}, {Resize(2, 2, NearestNeighborResampling), CropToSize(1, 1, CenterAnchor)}, {FlipHorizontal()}, {FlipVertical()}, {Resize(2, 2, NearestNeighborResampling), Resize(1, 1, NearestNeighborResampling)}, {Resize(2, 2, NearestNeighborResampling), ResizeToFit(1, 1, NearestNeighborResampling)}, {Resize(2, 2, NearestNeighborResampling), ResizeToFill(1, 1, NearestNeighborResampling, CenterAnchor)}, {Rotate(45, color.NRGBA{0, 0, 0, 0}, NearestNeighborInterpolation)}, {Rotate90()}, {Rotate180()}, {Rotate270()}, {Transpose()}, {Transverse()}, {Brightness(10)}, {ColorBalance(10, 10, 10)}, {ColorFunc(func(r0, g0, b0, a0 float32) (r, g, b, a float32) { return 1, 1, 1, 1 })}, {Colorize(240, 50, 100)}, {ColorspaceLinearToSRGB()}, {ColorspaceSRGBToLinear()}, {Contrast(10)}, {Convolution([]float32{-1, -1, 0, -1, 1, 1, 0, 1, 1}, false, false, false, 0)}, {Gamma(1.1)}, {GaussianBlur(3)}, {Grayscale()}, {Hue(90)}, {Invert()}, {Maximum(3, true)}, {Minimum(3, true)}, {Mean(3, true)}, {Median(3, true)}, {Pixelate(3)}, {Saturation(10)}, {Sepia(10)}, {Sigmoid(0.5, 5)}, {Sobel()}, {UnsharpMask(1, 1.5, 0.001)}, } for i, f := range filters { src := image.NewNRGBA(image.Rect(1, 1, 2, 2)) src.Pix = []uint8{255, 255, 255, 255} g := New(f...) dst := image.NewNRGBA(image.Rect(-100, -100, -95, -95)) g.Draw(dst, src) for x := dst.Bounds().Min.X; x < dst.Bounds().Max.X; x++ { for y := dst.Bounds().Min.Y; y < dst.Bounds().Max.Y; y++ { failed := false if x == -100 && y == -100 { if (color.NRGBAModel.Convert(dst.At(x, y)).(color.NRGBA) == color.NRGBA{0, 0, 0, 0}) { failed = true } } else { if (color.NRGBAModel.Convert(dst.At(x, y)).(color.NRGBA) != color.NRGBA{0, 0, 0, 0}) { failed = true } } if failed { t.Errorf("test draw pos failed: %d %#v %#v", i, f, dst.Pix) } } } } } func loadImage(t *testing.T, filename string) image.Image { f, err := os.Open(filename) if err != nil { t.Fatalf("os.Open (%q) failed: %v", filename, err) } img, _, err := image.Decode(f) if err != nil { t.Fatalf("image.Decode (%q) failed: %v", filename, err) } return img } func loadImageNRGBA(t *testing.T, filename string) *image.NRGBA { img := loadImage(t, filename) nrgba := image.NewNRGBA(img.Bounds()) New().Draw(nrgba, img) return nrgba } func TestGolden(t *testing.T) { filters := map[string]Filter{ "resize": Resize(100, 0, LanczosResampling), "crop_to_size": CropToSize(100, 100, LeftAnchor), "rotate_180": Rotate180(), "rotate_30": Rotate(30, color.Transparent, CubicInterpolation), "brightness_increase": Brightness(30), "brightness_decrease": Brightness(-30), "contrast_increase": Contrast(30), "contrast_decrease": Contrast(-30), "saturation_increase": Saturation(50), "saturation_decrease": Saturation(-50), "gamma_1.5": Gamma(1.5), "gamma_0.5": Gamma(0.5), "gaussian_blur": GaussianBlur(1), "unsharp_mask": UnsharpMask(1, 1, 0), "sigmoid": Sigmoid(0.5, 7), "pixelate": Pixelate(5), "colorize": Colorize(240, 50, 100), "grayscale": Grayscale(), "sepia": Sepia(100), "invert": Invert(), "mean": Mean(5, true), "median": Median(5, true), "minimum": Minimum(5, true), "maximum": Maximum(5, true), "hue_rotate": Hue(45), "color_balance": ColorBalance(10, -10, -10), "color_func": ColorFunc( func(r0, g0, b0, a0 float32) (r, g, b, a float32) { r = 1 - r0 g = g0 + 0.1 b = 0 a = a0 return r, g, b, a }, ), "convolution_emboss": Convolution( []float32{ -1, -1, 0, -1, 1, 1, 0, 1, 1, }, false, false, false, 0, ), } src := loadImage(t, "testdata/src.png") for name, filter := range filters { g := New(filter) dst := image.NewNRGBA(g.Bounds(src.Bounds())) g.Draw(dst, src) want := loadImageNRGBA(t, "testdata/dst_"+name+".png") if !goldenEqual(dst, want) { t.Errorf("resulting image differs from golden: %s", name) } } } // goldenEqual compares two NRGBA images. It is used in golden tests only. // All the golden images are generated on amd64 architecture. Due to differences // in floating-point rounding on different architectures, we need to add some // level of tolerance when comparing images on architectures other than amd64. // See https://golang.org/ref/spec#Floating_point_operators for information on // fused multiply and add (FMA) instruction. func goldenEqual(img1, img2 *image.NRGBA) bool { maxDiff := 0 if runtime.GOARCH != "amd64" { maxDiff = 1 } if !img1.Rect.Eq(img2.Rect) { return false } if len(img1.Pix) != len(img2.Pix) { return false } for i := 0; i < len(img1.Pix); i++ { diff := int(img1.Pix[i]) - int(img2.Pix[i]) if diff < 0 { diff = -diff } if diff > maxDiff { return false } } return true } func BenchmarkWorkers(b *testing.B) { file, err := os.Open("testdata/src.jpg") if err != nil { b.Fatalf("failed to open test image: %v", err) } src, _, err := image.Decode(file) if err != nil { b.Fatalf("failed to decode test image: %v", err) } runBench := func(b *testing.B, workers int) { options := &Options{Workers: workers} g := NewWithOptions(*options, Resize(150, 0, LanczosResampling)) dst := image.NewNRGBA(g.Bounds(src.Bounds())) b.ReportAllocs() b.ResetTimer() for b.Loop() { g.Draw(dst, src) } } runBenchPara := func(b *testing.B, workers int) { b.RunParallel(func(pb *testing.PB) { options := &Options{Workers: workers} g := NewWithOptions(*options, Resize(150, 0, LanczosResampling)) dst := image.NewNRGBA(g.Bounds(src.Bounds())) b.ReportAllocs() for pb.Next() { g.Draw(dst, src) } }) } b.Run("workers default", func(b *testing.B) { runBench(b, 0) }) b.Run("workers 1", func(b *testing.B) { runBench(b, 1) }) b.Run("workers 10", func(b *testing.B) { runBench(b, 10) }) b.Run("workers default parallel", func(b *testing.B) { runBenchPara(b, 0) }) b.Run("workers 1 parallel", func(b *testing.B) { runBenchPara(b, 1) }) b.Run("workers 10 parallel", func(b *testing.B) { runBenchPara(b, 10) }) } func BenchmarkFilter(b *testing.B) { file, err := os.Open("testdata/src.jpg") if err != nil { b.Fatalf("failed to open test image: %v", err) } src, _, err := image.Decode(file) if err != nil { b.Fatalf("failed to decode test image: %v", err) } filters := []struct { name string filter Filter }{ {"Resize Lanczos", Resize(150, 0, LanczosResampling)}, {"Resize Cubic", Resize(150, 0, CubicResampling)}, {"Resize Linear", Resize(150, 0, LinearResampling)}, {"Resize Box", Resize(150, 0, BoxResampling)}, {"Resize Nearest", Resize(150, 0, NearestNeighborResampling)}, {"Crop", Crop(image.Rect(50, 50, 200, 200))}, {"CropToSize", CropToSize(150, 150, CenterAnchor)}, {"FlipHorizontal", FlipHorizontal()}, {"FlipVertical", FlipVertical()}, {"Transpose", Transpose()}, {"Transverse", Transverse()}, {"Rotate90", Rotate90()}, {"Rotate180", Rotate180()}, {"Rotate270", Rotate270()}, {"Rotate", Rotate(30, color.Transparent, CubicInterpolation)}, {"Brightness", Brightness(30)}, {"Contrast", Contrast(30)}, {"Saturation", Saturation(50)}, {"Gamma", Gamma(1.5)}, {"GaussianBlur", GaussianBlur(1)}, {"UnsharpMask", UnsharpMask(1, 1, 0)}, {"Sigmoid", Sigmoid(0.5, 7)}, {"Pixelate", Pixelate(5)}, {"Colorize", Colorize(240, 50, 100)}, {"ColorBalance", ColorBalance(10, -10, -10)}, {"Threshold", Threshold(50)}, {"Hue", Hue(45)}, {"Grayscale", Grayscale()}, {"Sepia", Sepia(100)}, {"Invert", Invert()}, {"ColorFunc", ColorFunc( func(r0, g0, b0, a0 float32) (r, g, b, a float32) { r = 1 - r0 g = g0 + 0.1 b = 0 a = a0 return r, g, b, a }, )}, {"ColorspaceSRGBToLinear", ColorspaceSRGBToLinear()}, {"ColorspaceLinearToSRGB", ColorspaceLinearToSRGB()}, {"Mean", Mean(5, true)}, {"Median", Median(5, true)}, {"Minimum", Minimum(5, true)}, {"Maximum", Maximum(5, true)}, {"Convolution", Convolution( []float32{ -1, -1, 0, -1, 1, 1, 0, 1, 1, }, false, false, false, 0, )}, {"Sobel", Sobel()}, } for _, f := range filters { b.Run(f.name, func(b *testing.B) { g := New(f.filter) dst := image.NewNRGBA(g.Bounds(src.Bounds())) b.ReportAllocs() b.ResetTimer() for b.Loop() { g.Draw(dst, src) } }) } } gift-0.2.0/go.mod000066400000000000000000000000511513354670200135520ustar00rootroot00000000000000module github.com/gohugoio/gift go 1.24 gift-0.2.0/pixels.go000066400000000000000000000260751513354670200143150ustar00rootroot00000000000000package gift import ( "image" "image/color" "image/draw" "sync" ) type pixel struct { r, g, b, a float32 } type pixelSrcDst struct { src []pixel dst []pixel } type imageType int const ( itGeneric imageType = iota itNRGBA itNRGBA64 itRGBA itRGBA64 itYCbCr itGray itGray16 itPaletted ) type pixelGetter struct { it imageType bounds image.Rectangle image image.Image nrgba *image.NRGBA nrgba64 *image.NRGBA64 rgba *image.RGBA rgba64 *image.RGBA64 gray *image.Gray gray16 *image.Gray16 ycbcr *image.YCbCr paletted *image.Paletted palette []pixel } func newPixelGetter(img image.Image) *pixelGetter { switch img := img.(type) { case *image.NRGBA: return &pixelGetter{ it: itNRGBA, bounds: img.Bounds(), nrgba: img, } case *image.NRGBA64: return &pixelGetter{ it: itNRGBA64, bounds: img.Bounds(), nrgba64: img, } case *image.RGBA: return &pixelGetter{ it: itRGBA, bounds: img.Bounds(), rgba: img, } case *image.RGBA64: return &pixelGetter{ it: itRGBA64, bounds: img.Bounds(), rgba64: img, } case *image.Gray: return &pixelGetter{ it: itGray, bounds: img.Bounds(), gray: img, } case *image.Gray16: return &pixelGetter{ it: itGray16, bounds: img.Bounds(), gray16: img, } case *image.YCbCr: return &pixelGetter{ it: itYCbCr, bounds: img.Bounds(), ycbcr: img, } case *image.Paletted: return &pixelGetter{ it: itPaletted, bounds: img.Bounds(), paletted: img, palette: convertPalette(img.Palette), } default: return &pixelGetter{ it: itGeneric, bounds: img.Bounds(), image: img, } } } const ( qf8 = 1.0 / 0xff qf16 = 1.0 / 0xffff epal = qf16 * qf16 / 2 ) func pixelFromColor(c color.Color) (px pixel) { r16, g16, b16, a16 := c.RGBA() switch a16 { case 0: px = pixel{0, 0, 0, 0} case 0xffff: r := float32(r16) * qf16 g := float32(g16) * qf16 b := float32(b16) * qf16 px = pixel{r, g, b, 1} default: q := float32(1) / float32(a16) r := float32(r16) * q g := float32(g16) * q b := float32(b16) * q a := float32(a16) * qf16 px = pixel{r, g, b, a} } return px } func convertPalette(p []color.Color) []pixel { pal := make([]pixel, len(p)) for i := range p { pal[i] = pixelFromColor(p[i]) } return pal } func getPaletteIndex(pal []pixel, px pixel) int { var k int var dmin float32 = 4 for i, palpx := range pal { d := px.r - palpx.r dcur := d * d d = px.g - palpx.g dcur += d * d d = px.b - palpx.b dcur += d * d d = px.a - palpx.a dcur += d * d if dcur < epal { return i } if dcur < dmin { dmin = dcur k = i } } return k } func (p *pixelGetter) getPixel(x, y int) pixel { switch p.it { case itNRGBA: i := p.nrgba.PixOffset(x, y) r := float32(p.nrgba.Pix[i+0]) * qf8 g := float32(p.nrgba.Pix[i+1]) * qf8 b := float32(p.nrgba.Pix[i+2]) * qf8 a := float32(p.nrgba.Pix[i+3]) * qf8 return pixel{r, g, b, a} case itNRGBA64: i := p.nrgba64.PixOffset(x, y) r := float32(uint16(p.nrgba64.Pix[i+0])<<8|uint16(p.nrgba64.Pix[i+1])) * qf16 g := float32(uint16(p.nrgba64.Pix[i+2])<<8|uint16(p.nrgba64.Pix[i+3])) * qf16 b := float32(uint16(p.nrgba64.Pix[i+4])<<8|uint16(p.nrgba64.Pix[i+5])) * qf16 a := float32(uint16(p.nrgba64.Pix[i+6])<<8|uint16(p.nrgba64.Pix[i+7])) * qf16 return pixel{r, g, b, a} case itRGBA: i := p.rgba.PixOffset(x, y) a8 := p.rgba.Pix[i+3] switch a8 { case 0xff: r := float32(p.rgba.Pix[i+0]) * qf8 g := float32(p.rgba.Pix[i+1]) * qf8 b := float32(p.rgba.Pix[i+2]) * qf8 return pixel{r, g, b, 1} case 0: return pixel{0, 0, 0, 0} default: q := float32(1) / float32(a8) r := float32(p.rgba.Pix[i+0]) * q g := float32(p.rgba.Pix[i+1]) * q b := float32(p.rgba.Pix[i+2]) * q a := float32(a8) * qf8 return pixel{r, g, b, a} } case itRGBA64: i := p.rgba64.PixOffset(x, y) a16 := uint16(p.rgba64.Pix[i+6])<<8 | uint16(p.rgba64.Pix[i+7]) switch a16 { case 0xffff: r := float32(uint16(p.rgba64.Pix[i+0])<<8|uint16(p.rgba64.Pix[i+1])) * qf16 g := float32(uint16(p.rgba64.Pix[i+2])<<8|uint16(p.rgba64.Pix[i+3])) * qf16 b := float32(uint16(p.rgba64.Pix[i+4])<<8|uint16(p.rgba64.Pix[i+5])) * qf16 return pixel{r, g, b, 1} case 0: return pixel{0, 0, 0, 0} default: q := float32(1) / float32(a16) r := float32(uint16(p.rgba64.Pix[i+0])<<8|uint16(p.rgba64.Pix[i+1])) * q g := float32(uint16(p.rgba64.Pix[i+2])<<8|uint16(p.rgba64.Pix[i+3])) * q b := float32(uint16(p.rgba64.Pix[i+4])<<8|uint16(p.rgba64.Pix[i+5])) * q a := float32(a16) * qf16 return pixel{r, g, b, a} } case itGray: i := p.gray.PixOffset(x, y) v := float32(p.gray.Pix[i]) * qf8 return pixel{v, v, v, 1} case itGray16: i := p.gray16.PixOffset(x, y) v := float32(uint16(p.gray16.Pix[i+0])<<8|uint16(p.gray16.Pix[i+1])) * qf16 return pixel{v, v, v, 1} case itYCbCr: iy := (y-p.ycbcr.Rect.Min.Y)*p.ycbcr.YStride + (x - p.ycbcr.Rect.Min.X) var ic int switch p.ycbcr.SubsampleRatio { case image.YCbCrSubsampleRatio444: ic = (y-p.ycbcr.Rect.Min.Y)*p.ycbcr.CStride + (x - p.ycbcr.Rect.Min.X) case image.YCbCrSubsampleRatio422: ic = (y-p.ycbcr.Rect.Min.Y)*p.ycbcr.CStride + (x/2 - p.ycbcr.Rect.Min.X/2) case image.YCbCrSubsampleRatio420: ic = (y/2-p.ycbcr.Rect.Min.Y/2)*p.ycbcr.CStride + (x/2 - p.ycbcr.Rect.Min.X/2) case image.YCbCrSubsampleRatio440: ic = (y/2-p.ycbcr.Rect.Min.Y/2)*p.ycbcr.CStride + (x - p.ycbcr.Rect.Min.X) default: ic = p.ycbcr.COffset(x, y) } const ( max = 255 * 1e5 inv = 1.0 / max ) y1 := int32(p.ycbcr.Y[iy]) * 1e5 cb1 := int32(p.ycbcr.Cb[ic]) - 128 cr1 := int32(p.ycbcr.Cr[ic]) - 128 r1 := y1 + 140200*cr1 g1 := y1 - 34414*cb1 - 71414*cr1 b1 := y1 + 177200*cb1 r := float32(clampi32(r1, 0, max)) * inv g := float32(clampi32(g1, 0, max)) * inv b := float32(clampi32(b1, 0, max)) * inv return pixel{r, g, b, 1} case itPaletted: i := p.paletted.PixOffset(x, y) k := p.paletted.Pix[i] return p.palette[k] } return pixelFromColor(p.image.At(x, y)) } func (p *pixelGetter) getPixelRow(y int, buf *[]pixel) { *buf = (*buf)[:0] for x := p.bounds.Min.X; x != p.bounds.Max.X; x++ { *buf = append(*buf, p.getPixel(x, y)) } } func (p *pixelGetter) getPixelColumn(x int, buf *[]pixel) { *buf = (*buf)[:0] for y := p.bounds.Min.Y; y != p.bounds.Max.Y; y++ { *buf = append(*buf, p.getPixel(x, y)) } } func f32u8(val float32) uint8 { x := int64(val + 0.5) if x > 0xff { return 0xff } if x > 0 { return uint8(x) } return 0 } func f32u16(val float32) uint16 { x := int64(val + 0.5) if x > 0xffff { return 0xffff } if x > 0 { return uint16(x) } return 0 } func clampi32(val, min, max int32) int32 { if val > max { return max } if val > min { return val } return 0 } type pixelSetter struct { it imageType bounds image.Rectangle image draw.Image nrgba *image.NRGBA nrgba64 *image.NRGBA64 rgba *image.RGBA rgba64 *image.RGBA64 gray *image.Gray gray16 *image.Gray16 paletted *image.Paletted palette []pixel } func newPixelSetter(img draw.Image) *pixelSetter { switch img := img.(type) { case *image.NRGBA: return &pixelSetter{ it: itNRGBA, bounds: img.Bounds(), nrgba: img, } case *image.NRGBA64: return &pixelSetter{ it: itNRGBA64, bounds: img.Bounds(), nrgba64: img, } case *image.RGBA: return &pixelSetter{ it: itRGBA, bounds: img.Bounds(), rgba: img, } case *image.RGBA64: return &pixelSetter{ it: itRGBA64, bounds: img.Bounds(), rgba64: img, } case *image.Gray: return &pixelSetter{ it: itGray, bounds: img.Bounds(), gray: img, } case *image.Gray16: return &pixelSetter{ it: itGray16, bounds: img.Bounds(), gray16: img, } case *image.Paletted: return &pixelSetter{ it: itPaletted, bounds: img.Bounds(), paletted: img, palette: convertPalette(img.Palette), } default: return &pixelSetter{ it: itGeneric, bounds: img.Bounds(), image: img, } } } func (p *pixelSetter) setPixel(x, y int, px pixel) { if !image.Pt(x, y).In(p.bounds) { return } switch p.it { case itNRGBA: i := p.nrgba.PixOffset(x, y) p.nrgba.Pix[i+0] = f32u8(px.r * 0xff) p.nrgba.Pix[i+1] = f32u8(px.g * 0xff) p.nrgba.Pix[i+2] = f32u8(px.b * 0xff) p.nrgba.Pix[i+3] = f32u8(px.a * 0xff) case itNRGBA64: r16 := f32u16(px.r * 0xffff) g16 := f32u16(px.g * 0xffff) b16 := f32u16(px.b * 0xffff) a16 := f32u16(px.a * 0xffff) i := p.nrgba64.PixOffset(x, y) p.nrgba64.Pix[i+0] = uint8(r16 >> 8) p.nrgba64.Pix[i+1] = uint8(r16 & 0xff) p.nrgba64.Pix[i+2] = uint8(g16 >> 8) p.nrgba64.Pix[i+3] = uint8(g16 & 0xff) p.nrgba64.Pix[i+4] = uint8(b16 >> 8) p.nrgba64.Pix[i+5] = uint8(b16 & 0xff) p.nrgba64.Pix[i+6] = uint8(a16 >> 8) p.nrgba64.Pix[i+7] = uint8(a16 & 0xff) case itRGBA: fa := px.a * 0xff i := p.rgba.PixOffset(x, y) p.rgba.Pix[i+0] = f32u8(px.r * fa) p.rgba.Pix[i+1] = f32u8(px.g * fa) p.rgba.Pix[i+2] = f32u8(px.b * fa) p.rgba.Pix[i+3] = f32u8(fa) case itRGBA64: fa := px.a * 0xffff r16 := f32u16(px.r * fa) g16 := f32u16(px.g * fa) b16 := f32u16(px.b * fa) a16 := f32u16(fa) i := p.rgba64.PixOffset(x, y) p.rgba64.Pix[i+0] = uint8(r16 >> 8) p.rgba64.Pix[i+1] = uint8(r16 & 0xff) p.rgba64.Pix[i+2] = uint8(g16 >> 8) p.rgba64.Pix[i+3] = uint8(g16 & 0xff) p.rgba64.Pix[i+4] = uint8(b16 >> 8) p.rgba64.Pix[i+5] = uint8(b16 & 0xff) p.rgba64.Pix[i+6] = uint8(a16 >> 8) p.rgba64.Pix[i+7] = uint8(a16 & 0xff) case itGray: i := p.gray.PixOffset(x, y) p.gray.Pix[i] = f32u8((0.299*px.r + 0.587*px.g + 0.114*px.b) * px.a * 0xff) case itGray16: i := p.gray16.PixOffset(x, y) y16 := f32u16((0.299*px.r + 0.587*px.g + 0.114*px.b) * px.a * 0xffff) p.gray16.Pix[i+0] = uint8(y16 >> 8) p.gray16.Pix[i+1] = uint8(y16 & 0xff) case itPaletted: px1 := pixel{ minf32(maxf32(px.r, 0), 1), minf32(maxf32(px.g, 0), 1), minf32(maxf32(px.b, 0), 1), minf32(maxf32(px.a, 0), 1), } i := p.paletted.PixOffset(x, y) k := getPaletteIndex(p.palette, px1) p.paletted.Pix[i] = uint8(k) case itGeneric: r16 := f32u16(px.r * 0xffff) g16 := f32u16(px.g * 0xffff) b16 := f32u16(px.b * 0xffff) a16 := f32u16(px.a * 0xffff) p.image.Set(x, y, color.NRGBA64{r16, g16, b16, a16}) } } func (p *pixelSetter) setPixelRow(y int, buf []pixel) { for i, x := 0, p.bounds.Min.X; i < len(buf); i, x = i+1, x+1 { p.setPixel(x, y, buf[i]) } } func (p *pixelSetter) setPixelColumn(x int, buf []pixel) { for i, y := 0, p.bounds.Min.Y; i < len(buf); i, y = i+1, y+1 { p.setPixel(x, y, buf[i]) } } var pixelBufPool = &sync.Pool{ New: func() any { return &pixelSrcDst{ src: make([]pixel, 0), dst: make([]pixel, 0), } }, } func getPixelBuf(srcLen, dstLen int) *pixelSrcDst { v := pixelBufPool.Get().(*pixelSrcDst) if srcLen > cap(v.src) { v.src = make([]pixel, srcLen) } if dstLen > cap(v.dst) { v.dst = make([]pixel, dstLen) } v.src = v.src[:srcLen] v.dst = v.dst[:dstLen] return v } func putPixelBuf(buf *pixelSrcDst) { buf.src = buf.src[:0] buf.dst = buf.dst[:0] pixelBufPool.Put(buf) } gift-0.2.0/pixels_test.go000066400000000000000000000363341513354670200153530ustar00rootroot00000000000000package gift import ( "image" "image/color" "image/draw" "math" "testing" ) func TestNewPixelGetter(t *testing.T) { var img image.Image var pg *pixelGetter img = image.NewNRGBA(image.Rect(0, 0, 1, 1)) pg = newPixelGetter(img) if pg.it != itNRGBA || pg.nrgba == nil || !img.Bounds().Eq(pg.bounds) { t.Error("newPixelGetter NRGBA") } img = image.NewNRGBA64(image.Rect(0, 0, 1, 1)) pg = newPixelGetter(img) if pg.it != itNRGBA64 || pg.nrgba64 == nil || !img.Bounds().Eq(pg.bounds) { t.Error("newPixelGetter NRGBA64") } img = image.NewRGBA(image.Rect(0, 0, 1, 1)) pg = newPixelGetter(img) if pg.it != itRGBA || pg.rgba == nil || !img.Bounds().Eq(pg.bounds) { t.Error("newPixelGetter RGBA") } img = image.NewRGBA64(image.Rect(0, 0, 1, 1)) pg = newPixelGetter(img) if pg.it != itRGBA64 || pg.rgba64 == nil || !img.Bounds().Eq(pg.bounds) { t.Error("newPixelGetter RGBA64") } img = image.NewGray(image.Rect(0, 0, 1, 1)) pg = newPixelGetter(img) if pg.it != itGray || pg.gray == nil || !img.Bounds().Eq(pg.bounds) { t.Error("newPixelGetter Gray") } img = image.NewGray16(image.Rect(0, 0, 1, 1)) pg = newPixelGetter(img) if pg.it != itGray16 || pg.gray16 == nil || !img.Bounds().Eq(pg.bounds) { t.Error("newPixelGetter Gray16") } img = image.NewYCbCr(image.Rect(0, 0, 1, 1), image.YCbCrSubsampleRatio422) pg = newPixelGetter(img) if pg.it != itYCbCr || pg.ycbcr == nil || !img.Bounds().Eq(pg.bounds) { t.Error("newPixelGetter YCbCr") } img = image.NewUniform(color.NRGBA64{0, 0, 0, 0}) pg = newPixelGetter(img) if pg.it != itGeneric || pg.image == nil || !img.Bounds().Eq(pg.bounds) { t.Error("newPixelGetter Generic(Uniform)") } img = image.NewAlpha(image.Rect(0, 0, 1, 1)) pg = newPixelGetter(img) if pg.it != itGeneric || pg.image == nil || !img.Bounds().Eq(pg.bounds) { t.Error("newPixelGetter Generic(Alpha)") } } func comparePixels(px1, px2 pixel, dif float64) bool { if math.Abs(float64(px1.r)-float64(px2.r)) > dif { return false } if math.Abs(float64(px1.g)-float64(px2.g)) > dif { return false } if math.Abs(float64(px1.b)-float64(px2.b)) > dif { return false } if math.Abs(float64(px1.a)-float64(px2.a)) > dif { return false } return true } func compareColorsNRGBA(c1, c2 color.NRGBA, dif int) bool { if math.Abs(float64(c1.R)-float64(c2.R)) > float64(dif) { return false } if math.Abs(float64(c1.G)-float64(c2.G)) > float64(dif) { return false } if math.Abs(float64(c1.B)-float64(c2.B)) > float64(dif) { return false } if math.Abs(float64(c1.A)-float64(c2.A)) > float64(dif) { return false } return true } func TestGetPixel(t *testing.T) { var pg *pixelGetter // RGBA, NRGBA, RGBA64, NRGBA64 palette := []color.Color{ color.NRGBA{0, 0, 0, 0}, color.NRGBA{255, 255, 255, 255}, color.NRGBA{50, 100, 150, 255}, color.NRGBA{150, 100, 50, 200}, } images1 := []draw.Image{ image.NewRGBA(image.Rect(-1, -2, 3, 4)), image.NewRGBA64(image.Rect(-1, -2, 3, 4)), image.NewNRGBA(image.Rect(-1, -2, 3, 4)), image.NewNRGBA64(image.Rect(-1, -2, 3, 4)), image.NewPaletted(image.Rect(-1, -2, 3, 4), palette), } colors1 := []struct { c color.NRGBA px pixel }{ {color.NRGBA{0, 0, 0, 0}, pixel{0, 0, 0, 0}}, {color.NRGBA{255, 255, 255, 255}, pixel{1, 1, 1, 1}}, {color.NRGBA{50, 100, 150, 255}, pixel{0.196, 0.392, 0.588, 1}}, {color.NRGBA{150, 100, 50, 200}, pixel{0.588, 0.392, 0.196, 0.784}}, } for _, img := range images1 { pg = newPixelGetter(img) for _, k := range colors1 { for _, x := range []int{-1, 0, 2} { for _, y := range []int{-2, 0, 3} { img.Set(x, y, k.c) px := pg.getPixel(x, y) if !comparePixels(k.px, px, 0.005) { t.Errorf("getPixel %T %v %dx%d %v %v", img, k.c, x, y, k.px, px) } } } } } // Uniform (Generic) for _, k := range colors1 { img := image.NewUniform(k.c) pg = newPixelGetter(img) for _, x := range []int{-1, 0, 2} { for _, y := range []int{-2, 0, 3} { px := pg.getPixel(x, y) if !comparePixels(k.px, px, 0.005) { t.Errorf("getPixel %T %v %dx%d %v %v", img, k.c, x, y, k.px, px) } } } } // YCbCr colors2 := []struct { c color.NRGBA px pixel }{ {color.NRGBA{0, 0, 0, 255}, pixel{0, 0, 0, 1}}, {color.NRGBA{255, 255, 255, 255}, pixel{1, 1, 1, 1}}, {color.NRGBA{50, 100, 150, 255}, pixel{0.196, 0.392, 0.588, 1}}, {color.NRGBA{150, 100, 50, 255}, pixel{0.588, 0.392, 0.196, 1}}, } for _, k := range colors2 { for _, sr := range []image.YCbCrSubsampleRatio{ image.YCbCrSubsampleRatio444, image.YCbCrSubsampleRatio422, image.YCbCrSubsampleRatio420, image.YCbCrSubsampleRatio440, image.YCbCrSubsampleRatio410, image.YCbCrSubsampleRatio411, } { img := image.NewYCbCr(image.Rect(-1, -2, 3, 4), sr) pg = newPixelGetter(img) for _, x := range []int{-1, 0, 2} { for _, y := range []int{-2, 0, 3} { iy := img.YOffset(x, y) ic := img.COffset(x, y) img.Y[iy], img.Cb[ic], img.Cr[ic] = color.RGBToYCbCr(k.c.R, k.c.G, k.c.B) px := pg.getPixel(x, y) if !comparePixels(k.px, px, 0.005) { t.Errorf("getPixel %T %v %dx%d %v %v", img, k.c, x, y, k.px, px) } } } } } // Gray, Gray16 images2 := []draw.Image{ image.NewGray(image.Rect(-1, -2, 3, 4)), image.NewGray16(image.Rect(-1, -2, 3, 4)), } colors3 := []struct { c color.NRGBA px pixel }{ {color.NRGBA{0, 0, 0, 0}, pixel{0, 0, 0, 1}}, {color.NRGBA{255, 255, 255, 255}, pixel{1, 1, 1, 1}}, {color.NRGBA{50, 100, 150, 255}, pixel{0.356, 0.356, 0.356, 1}}, {color.NRGBA{150, 100, 50, 200}, pixel{0.337, 0.337, 0.337, 1}}, } for _, img := range images2 { pg = newPixelGetter(img) for _, k := range colors3 { for _, x := range []int{-1, 0, 2} { for _, y := range []int{-2, 0, 3} { img.Set(x, y, k.c) px := pg.getPixel(x, y) if !comparePixels(k.px, px, 0.005) { t.Errorf("getPixel %T %v %dx%d %v %v", img, k.c, x, y, k.px, px) } } } } } } func comparePixelSlices(s1, s2 []pixel, dif float64) bool { if len(s1) != len(s2) { return false } for i := 1; i < len(s1); i++ { if !comparePixels(s1[i], s2[i], dif) { return false } } return true } func TestGetPixelRow(t *testing.T) { colors := []color.NRGBA{ {0, 0, 0, 0}, {255, 255, 255, 255}, {50, 100, 150, 255}, {150, 100, 50, 200}, } pixels := []pixel{ {0, 0, 0, 0}, {1, 1, 1, 1}, {0.196, 0.392, 0.588, 1}, {0.588, 0.392, 0.196, 0.784}, } img := image.NewNRGBA(image.Rect(-1, -2, 3, 2)) pg := newPixelGetter(img) var row []pixel for y := img.Bounds().Min.Y; y < img.Bounds().Max.Y; y++ { for x := img.Bounds().Min.X; x < img.Bounds().Max.X; x++ { img.Set(x, y, colors[x-img.Bounds().Min.X]) } pg.getPixelRow(y, &row) if !comparePixelSlices(row, pixels, 0.005) { t.Errorf("getPixelRow y=%d %v %v", y, row, pixels) } } } func TestGetPixelColumn(t *testing.T) { colors := []color.NRGBA{ {0, 0, 0, 0}, {255, 255, 255, 255}, {50, 100, 150, 255}, {150, 100, 50, 200}, } pixels := []pixel{ {0, 0, 0, 0}, {1, 1, 1, 1}, {0.196, 0.392, 0.588, 1}, {0.588, 0.392, 0.196, 0.784}, } img := image.NewNRGBA(image.Rect(-1, -2, 3, 2)) pg := newPixelGetter(img) var column []pixel for x := img.Bounds().Min.X; x < img.Bounds().Max.X; x++ { for y := img.Bounds().Min.Y; y < img.Bounds().Max.Y; y++ { img.Set(x, y, colors[y-img.Bounds().Min.Y]) } pg.getPixelColumn(x, &column) if !comparePixelSlices(column, pixels, 0.005) { t.Errorf("getPixelColumn x=%d %v %v", x, column, pixels) } } } func TestF32u8(t *testing.T) { testData := []struct { x float32 y uint8 }{ {-1, 0}, {0, 0}, {100, 100}, {255, 255}, {256, 255}, } for _, p := range testData { v := f32u8(p.x) if v != p.y { t.Errorf("f32u8(%f) != %d: %d", p.x, p.y, v) } } } func TestF32u16(t *testing.T) { testData := []struct { x float32 y uint16 }{ {-1, 0}, {0, 0}, {1, 1}, {10000, 10000}, {65535, 65535}, {65536, 65535}, } for _, p := range testData { v := f32u16(p.x) if v != p.y { t.Errorf("f32u16(%f) != %d: %d", p.x, p.y, v) } } } func TestClampi32(t *testing.T) { testData := []struct { x int32 y int32 }{ {-1, 0}, {0, 0}, {1, 1}, {99, 99}, {100, 100}, {101, 100}, } for _, p := range testData { v := clampi32(p.x, 0, 100) if v != p.y { t.Errorf("clampi32(%d) != %d: %d", p.x, p.y, v) } } } func TestNewPixelSetter(t *testing.T) { var img draw.Image var pg *pixelSetter img = image.NewNRGBA(image.Rect(0, 0, 1, 1)) pg = newPixelSetter(img) if pg.it != itNRGBA || pg.nrgba == nil || !img.Bounds().Eq(pg.bounds) { t.Error("newPixelSetter NRGBA") } img = image.NewNRGBA64(image.Rect(0, 0, 1, 1)) pg = newPixelSetter(img) if pg.it != itNRGBA64 || pg.nrgba64 == nil || !img.Bounds().Eq(pg.bounds) { t.Error("newPixelSetter NRGBA64") } img = image.NewRGBA(image.Rect(0, 0, 1, 1)) pg = newPixelSetter(img) if pg.it != itRGBA || pg.rgba == nil || !img.Bounds().Eq(pg.bounds) { t.Error("newPixelSetter RGBA") } img = image.NewRGBA64(image.Rect(0, 0, 1, 1)) pg = newPixelSetter(img) if pg.it != itRGBA64 || pg.rgba64 == nil || !img.Bounds().Eq(pg.bounds) { t.Error("newPixelSetter RGBA64") } img = image.NewGray(image.Rect(0, 0, 1, 1)) pg = newPixelSetter(img) if pg.it != itGray || pg.gray == nil || !img.Bounds().Eq(pg.bounds) { t.Error("newPixelSetter Gray") } img = image.NewGray16(image.Rect(0, 0, 1, 1)) pg = newPixelSetter(img) if pg.it != itGray16 || pg.gray16 == nil || !img.Bounds().Eq(pg.bounds) { t.Error("newPixelSetter Gray16") } img = image.NewPaletted(image.Rect(0, 0, 1, 1), color.Palette{}) pg = newPixelSetter(img) if pg.it != itPaletted || pg.paletted == nil || !img.Bounds().Eq(pg.bounds) { t.Error("newPixelSetter Paletted") } img = image.NewAlpha(image.Rect(0, 0, 1, 1)) pg = newPixelSetter(img) if pg.it != itGeneric || pg.image == nil || !img.Bounds().Eq(pg.bounds) { t.Error("newPixelSetter Generic(Alpha)") } } func TestSetPixel(t *testing.T) { var ps *pixelSetter // RGBA, NRGBA, RGBA64, NRGBA64 images1 := []draw.Image{ image.NewRGBA(image.Rect(-1, -2, 3, 4)), image.NewRGBA64(image.Rect(-1, -2, 3, 4)), image.NewNRGBA(image.Rect(-1, -2, 3, 4)), image.NewNRGBA64(image.Rect(-1, -2, 3, 4)), } colors1 := []struct { c color.NRGBA px pixel }{ {color.NRGBA{0, 0, 0, 0}, pixel{0, 0, 0, 0}}, {color.NRGBA{0, 0, 0, 255}, pixel{0, 0, 0, 1}}, {color.NRGBA{255, 255, 255, 255}, pixel{1, 1, 1, 1}}, {color.NRGBA{50, 100, 150, 255}, pixel{0.196, 0.392, 0.588, 1}}, {color.NRGBA{150, 100, 50, 200}, pixel{0.588, 0.392, 0.196, 0.784}}, } for _, img := range images1 { ps = newPixelSetter(img) for _, k := range colors1 { for _, x := range []int{-1, 0, 2} { for _, y := range []int{-2, 0, 3} { ps.setPixel(x, y, k.px) c := color.NRGBAModel.Convert(img.At(x, y)).(color.NRGBA) if !compareColorsNRGBA(c, k.c, 1) { t.Errorf("setPixel %T %v %dx%d %v %v", img, k.px, x, y, k.c, c) } } } } } // Gray, Gray16 images2 := []draw.Image{ image.NewGray(image.Rect(-1, -2, 3, 4)), image.NewGray16(image.Rect(-1, -2, 3, 4)), } colors2 := []struct { c color.NRGBA px pixel }{ {color.NRGBA{0, 0, 0, 255}, pixel{0, 0, 0, 1}}, {color.NRGBA{255, 255, 255, 255}, pixel{1, 1, 1, 1}}, {color.NRGBA{110, 110, 110, 255}, pixel{0.2, 0.5, 0.7, 1}}, {color.NRGBA{55, 55, 55, 255}, pixel{0.2, 0.5, 0.7, 0.5}}, } for _, img := range images2 { ps = newPixelSetter(img) for _, k := range colors2 { for _, x := range []int{-1, 0, 2} { for _, y := range []int{-2, 0, 3} { ps.setPixel(x, y, k.px) c := color.NRGBAModel.Convert(img.At(x, y)).(color.NRGBA) if !compareColorsNRGBA(c, k.c, 1) { t.Errorf("setPixel %T %v %dx%d %v %v", img, k.px, x, y, k.c, c) } } } } } // Generic(Alpha) colors3 := []struct { c color.NRGBA px pixel }{ {color.NRGBA{255, 255, 255, 255}, pixel{0, 0, 0, 1}}, {color.NRGBA{255, 255, 255, 127}, pixel{0.2, 0.5, 0.7, 0.5}}, {color.NRGBA{255, 255, 255, 63}, pixel{0.1, 0.2, 0.3, 0.25}}, } img := image.NewAlpha(image.Rect(-1, -2, 3, 4)) ps = newPixelSetter(img) for _, k := range colors3 { for _, x := range []int{-1, 0, 2} { for _, y := range []int{-2, 0, 3} { ps.setPixel(x, y, k.px) c := color.NRGBAModel.Convert(img.At(x, y)).(color.NRGBA) if !compareColorsNRGBA(c, k.c, 1) { t.Errorf("setPixel %T %v %dx%d %v %v", img, k.px, x, y, k.c, c) } } } } // Paletted images4 := []draw.Image{ image.NewPaletted( image.Rect(-1, -2, 3, 4), color.Palette{ color.NRGBA{0, 0, 0, 0}, color.NRGBA{0, 0, 0, 255}, color.NRGBA{255, 255, 255, 255}, color.NRGBA{50, 100, 150, 255}, color.NRGBA{150, 100, 50, 200}, color.NRGBA{1, 255, 255, 255}, color.NRGBA{2, 255, 255, 255}, color.NRGBA{3, 255, 255, 255}, }, ), } colors4 := []struct { c color.NRGBA px pixel }{ {color.NRGBA{0, 0, 0, 0}, pixel{0, 0, 0, 0}}, {color.NRGBA{0, 0, 0, 255}, pixel{0, 0, 0, 1}}, {color.NRGBA{255, 255, 255, 255}, pixel{1, 1, 1, 1}}, {color.NRGBA{50, 100, 150, 255}, pixel{0.196, 0.392, 0.588, 1}}, {color.NRGBA{150, 100, 50, 200}, pixel{0.588, 0.392, 0.196, 0.784}}, {color.NRGBA{0, 0, 0, 0}, pixel{0.1, 0.01, 0.001, 0.1}}, {color.NRGBA{0, 0, 0, 255}, pixel{0, 0, 0, 0.9}}, {color.NRGBA{255, 255, 255, 255}, pixel{1, 0.9, 1, 0.9}}, {color.NRGBA{1, 255, 255, 255}, pixel{0.001 / 255, 1, 1, 1}}, {color.NRGBA{1, 255, 255, 255}, pixel{1.001 / 255, 1, 1, 1}}, {color.NRGBA{2, 255, 255, 255}, pixel{2.001 / 255, 1, 1, 1}}, {color.NRGBA{3, 255, 255, 255}, pixel{3.001 / 255, 1, 1, 1}}, {color.NRGBA{3, 255, 255, 255}, pixel{4.001 / 255, 1, 1, 1}}, } for _, img := range images4 { ps = newPixelSetter(img) for _, k := range colors4 { for _, x := range []int{-1, 0, 2} { for _, y := range []int{-2, 0, 3} { ps.setPixel(x, y, k.px) c := color.NRGBAModel.Convert(img.At(x, y)).(color.NRGBA) if !compareColorsNRGBA(c, k.c, 0) { t.Errorf("setPixel %T %v %dx%d %v %v", img, k.px, x, y, k.c, c) } } } } } } func TestSetPixelRow(t *testing.T) { colors := []color.NRGBA{ {0, 0, 0, 0}, {255, 255, 255, 255}, {50, 100, 150, 255}, {150, 100, 50, 200}, } pixels := []pixel{ {0, 0, 0, 0}, {1, 1, 1, 1}, {0.196, 0.392, 0.588, 1}, {0.588, 0.392, 0.196, 0.784}, } img := image.NewNRGBA(image.Rect(-1, -2, 3, 2)) ps := newPixelSetter(img) for y := img.Bounds().Min.Y; y < img.Bounds().Max.Y; y++ { ps.setPixelRow(y, pixels) for x := img.Bounds().Min.X; x < img.Bounds().Max.X; x++ { c := img.At(x, y).(color.NRGBA) wantedColor := colors[x-img.Bounds().Min.X] if !compareColorsNRGBA(wantedColor, c, 1) { t.Errorf("setPixelRow y=%d x=%d %v %v", y, x, wantedColor, c) } } } } func TestSetPixelColumn(t *testing.T) { colors := []color.NRGBA{ {0, 0, 0, 0}, {255, 255, 255, 255}, {50, 100, 150, 255}, {150, 100, 50, 200}, } pixels := []pixel{ {0, 0, 0, 0}, {1, 1, 1, 1}, {0.196, 0.392, 0.588, 1}, {0.588, 0.392, 0.196, 0.784}, } img := image.NewNRGBA(image.Rect(-1, -2, 3, 2)) ps := newPixelSetter(img) for x := img.Bounds().Min.X; x < img.Bounds().Max.X; x++ { ps.setPixelColumn(x, pixels) for y := img.Bounds().Min.Y; y < img.Bounds().Max.Y; y++ { c := img.At(x, y).(color.NRGBA) wantedColor := colors[y-img.Bounds().Min.Y] if !compareColorsNRGBA(wantedColor, c, 1) { t.Errorf("setPixelColumn x=%d y=%d %v %v", x, y, wantedColor, c) } } } } gift-0.2.0/rank.go000066400000000000000000000116731513354670200137420ustar00rootroot00000000000000package gift import ( "image" "image/draw" ) type rankMode int const ( rankMedian rankMode = iota rankMin rankMax ) type rankFilter struct { ksize int disk bool mode rankMode } func (p *rankFilter) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { dstBounds = image.Rect(0, 0, srcBounds.Dx(), srcBounds.Dy()) return } func (p *rankFilter) Draw(dst draw.Image, src image.Image, options *Options) { if options == nil { options = &defaultOptions } srcb := src.Bounds() dstb := dst.Bounds() if srcb.Dx() <= 0 || srcb.Dy() <= 0 { return } ksize := p.ksize if ksize%2 == 0 { ksize-- } if ksize <= 1 { copyimage(dst, src, options) return } kradius := ksize / 2 opaque := isOpaque(src) var disk []float32 if p.disk { disk = genDisk(ksize) } pixGetter := newPixelGetter(src) pixSetter := newPixelSetter(dst) parallelize(options.Workers, srcb.Min.Y, srcb.Max.Y, func(start, stop int) { buf := getPixelBuf(0, 0) defer putPixelBuf(buf) var rbuf, gbuf, bbuf, abuf []float32 if p.mode == rankMedian { rbuf = make([]float32, 0, ksize*ksize) gbuf = make([]float32, 0, ksize*ksize) bbuf = make([]float32, 0, ksize*ksize) if !opaque { abuf = make([]float32, 0, ksize*ksize) } } for y := start; y < stop; y++ { // Init buffer. buf.src = buf.src[:0] for i := srcb.Min.X - kradius; i <= srcb.Min.X+kradius; i++ { for j := y - kradius; j <= y+kradius; j++ { kx, ky := i, j if kx < srcb.Min.X { kx = srcb.Min.X } else if kx > srcb.Max.X-1 { kx = srcb.Max.X - 1 } if ky < srcb.Min.Y { ky = srcb.Min.Y } else if ky > srcb.Max.Y-1 { ky = srcb.Max.Y - 1 } buf.src = append(buf.src, pixGetter.getPixel(kx, ky)) } } for x := srcb.Min.X; x < srcb.Max.X; x++ { var r, g, b, a float32 if p.mode == rankMedian { rbuf = rbuf[:0] gbuf = gbuf[:0] bbuf = bbuf[:0] if !opaque { abuf = abuf[:0] } } else if p.mode == rankMin { r, g, b, a = 1, 1, 1, 1 } else if p.mode == rankMax { r, g, b, a = 0, 0, 0, 0 } sz := 0 for i := 0; i < ksize; i++ { for j := 0; j < ksize; j++ { if p.disk { if disk[i*ksize+j] == 0 { continue } } px := buf.src[i*ksize+j] if p.mode == rankMedian { rbuf = append(rbuf, px.r) gbuf = append(gbuf, px.g) bbuf = append(bbuf, px.b) if !opaque { abuf = append(abuf, px.a) } } else if p.mode == rankMin { r = minf32(r, px.r) g = minf32(g, px.g) b = minf32(b, px.b) if !opaque { a = minf32(a, px.a) } } else if p.mode == rankMax { r = maxf32(r, px.r) g = maxf32(g, px.g) b = maxf32(b, px.b) if !opaque { a = maxf32(a, px.a) } } sz++ } } if p.mode == rankMedian { sort(rbuf) sort(gbuf) sort(bbuf) if !opaque { sort(abuf) } idx := sz / 2 r, g, b = rbuf[idx], gbuf[idx], bbuf[idx] if !opaque { a = abuf[idx] } } if opaque { a = 1 } pixSetter.setPixel(dstb.Min.X+x-srcb.Min.X, dstb.Min.Y+y-srcb.Min.Y, pixel{r, g, b, a}) // Rotate buffer columns. if x < srcb.Max.X-1 { copy(buf.src[0:], buf.src[ksize:]) buf.src = buf.src[0 : ksize*(ksize-1)] kx := min(x+1+kradius, srcb.Max.X-1) for j := y - kradius; j <= y+kradius; j++ { ky := j if ky < srcb.Min.Y { ky = srcb.Min.Y } else if ky > srcb.Max.Y-1 { ky = srcb.Max.Y - 1 } buf.src = append(buf.src, pixGetter.getPixel(kx, ky)) } } } } }) } // Median creates a median image filter. // Picks a median value per channel in neighborhood for each pixel. // The ksize parameter is the kernel size. It must be an odd positive integer (for example: 3, 5, 7). // If the disk parameter is true, a disk-shaped neighborhood will be used instead of a square neighborhood. func Median(ksize int, disk bool) Filter { return &rankFilter{ ksize: ksize, disk: disk, mode: rankMedian, } } // Minimum creates a local minimum image filter. // Picks a minimum value per channel in neighborhood for each pixel. // The ksize parameter is the kernel size. It must be an odd positive integer (for example: 3, 5, 7). // If the disk parameter is true, a disk-shaped neighborhood will be used instead of a square neighborhood. func Minimum(ksize int, disk bool) Filter { return &rankFilter{ ksize: ksize, disk: disk, mode: rankMin, } } // Maximum creates a local maximum image filter. // Picks a maximum value per channel in neighborhood for each pixel. // The ksize parameter is the kernel size. It must be an odd positive integer (for example: 3, 5, 7). // If the disk parameter is true, a disk-shaped neighborhood will be used instead of a square neighborhood. func Maximum(ksize int, disk bool) Filter { return &rankFilter{ ksize: ksize, disk: disk, mode: rankMax, } } gift-0.2.0/rank_test.go000066400000000000000000000276301513354670200150010ustar00rootroot00000000000000package gift import ( "image" "testing" ) func TestMedian(t *testing.T) { testData := []struct { desc string ksize int disk bool srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "median (0, false)", 0, false, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x11, 0x99, 0x55, 0x22, 0x66, 0xFF, 0x44, 0xFF, 0xCC, 0x00, 0x33, 0x77, 0xBB, 0x88, 0xEE, }, []uint8{ 0x11, 0x99, 0x55, 0x22, 0x66, 0xFF, 0x44, 0xFF, 0xCC, 0x00, 0x33, 0x77, 0xBB, 0x88, 0xEE, }, }, { "median (1, false)", 1, false, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x11, 0x99, 0x55, 0x22, 0x66, 0xFF, 0x44, 0xFF, 0xCC, 0x00, 0x33, 0x77, 0xBB, 0x88, 0xEE, }, []uint8{ 0x11, 0x99, 0x55, 0x22, 0x66, 0xFF, 0x44, 0xFF, 0xCC, 0x00, 0x33, 0x77, 0xBB, 0x88, 0xEE, }, }, { "median (2, false)", 2, false, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x11, 0x99, 0x55, 0x22, 0x66, 0xFF, 0x44, 0xFF, 0xCC, 0x00, 0x33, 0x77, 0xBB, 0x88, 0xEE, }, []uint8{ 0x11, 0x99, 0x55, 0x22, 0x66, 0xFF, 0x44, 0xFF, 0xCC, 0x00, 0x33, 0x77, 0xBB, 0x88, 0xEE, }, }, { "median (3, false)", 3, false, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x11, 0x99, 0x55, 0x22, 0x66, 0xFF, 0x44, 0xFF, 0xCC, 0x00, 0x33, 0x77, 0xBB, 0x88, 0xEE, }, []uint8{ 0x44, 0x55, 0x55, 0x55, 0x66, 0x44, 0x77, 0x88, 0x88, 0x66, 0x44, 0x77, 0x88, 0xBB, 0xCC, }, }, { "median (3, true)", 3, true, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x11, 0x99, 0x55, 0x22, 0x66, 0xFF, 0x44, 0xFF, 0xCC, 0x00, 0x33, 0x77, 0xBB, 0x88, 0xEE, }, []uint8{ 0x11, 0x55, 0x55, 0x55, 0x66, 0x44, 0x99, 0xBB, 0x88, 0x66, 0x33, 0x77, 0xBB, 0xBB, 0xEE, }, }, { "median (4, true)", 4, true, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x11, 0x99, 0x55, 0x22, 0x66, 0xFF, 0x44, 0xFF, 0xCC, 0x00, 0x33, 0x77, 0xBB, 0x88, 0xEE, }, []uint8{ 0x11, 0x55, 0x55, 0x55, 0x66, 0x44, 0x99, 0xBB, 0x88, 0x66, 0x33, 0x77, 0xBB, 0xBB, 0xEE, }, }, } for _, d := range testData { src := image.NewGray(d.srcb) src.Pix = d.srcPix f := Median(d.ksize, d.disk) dst := image.NewGray(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } testDataNRGBA := []struct { desc string ksize int disk bool srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "median nrgba (3, true)", 3, true, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0xBB, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0xEE, }, []uint8{ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0xBB, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0xBB, 0x00, 0x00, 0x00, 0xBB, 0x00, 0x00, 0x00, 0xEE, }, }, } for _, d := range testDataNRGBA { src := image.NewNRGBA(d.srcb) src.Pix = d.srcPix f := Median(d.ksize, d.disk) dst := image.NewNRGBA(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } // check no panics Median(5, false).Draw(image.NewGray(image.Rect(0, 0, 1, 1)), image.NewGray(image.Rect(0, 0, 1, 1)), nil) Median(5, false).Draw(image.NewGray(image.Rect(0, 0, 0, 0)), image.NewGray(image.Rect(0, 0, 0, 0)), nil) } func TestMinimum(t *testing.T) { testData := []struct { desc string ksize int disk bool srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "minimum (0, false)", 0, false, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x11, 0x99, 0x55, 0x22, 0x66, 0xFF, 0x44, 0xFF, 0xCC, 0x00, 0x33, 0x77, 0xBB, 0x88, 0xEE, }, []uint8{ 0x11, 0x99, 0x55, 0x22, 0x66, 0xFF, 0x44, 0xFF, 0xCC, 0x00, 0x33, 0x77, 0xBB, 0x88, 0xEE, }, }, { "minimum (1, false)", 1, false, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x11, 0x99, 0x55, 0x22, 0x66, 0xFF, 0x44, 0xFF, 0xCC, 0x00, 0x33, 0x77, 0xBB, 0x88, 0xEE, }, []uint8{ 0x11, 0x99, 0x55, 0x22, 0x66, 0xFF, 0x44, 0xFF, 0xCC, 0x00, 0x33, 0x77, 0xBB, 0x88, 0xEE, }, }, { "minimum (2, false)", 2, false, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x11, 0x99, 0x55, 0x22, 0x66, 0xFF, 0x44, 0xFF, 0xCC, 0x00, 0x33, 0x77, 0xBB, 0x88, 0xEE, }, []uint8{ 0x11, 0x99, 0x55, 0x22, 0x66, 0xFF, 0x44, 0xFF, 0xCC, 0x00, 0x33, 0x77, 0xBB, 0x88, 0xEE, }, }, { "minimum (3, false)", 3, false, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x11, 0x99, 0x55, 0x22, 0x66, 0xFF, 0x44, 0xFF, 0xCC, 0x00, 0x33, 0x77, 0xBB, 0x88, 0xEE, }, []uint8{ 0x11, 0x11, 0x22, 0x00, 0x00, 0x11, 0x11, 0x22, 0x00, 0x00, 0x33, 0x33, 0x44, 0x00, 0x00, }, }, { "minimum (3, true)", 3, true, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x11, 0x99, 0x55, 0x22, 0x66, 0xFF, 0x44, 0xFF, 0xCC, 0x00, 0x33, 0x77, 0xBB, 0x88, 0xEE, }, []uint8{ 0x11, 0x11, 0x22, 0x22, 0x00, 0x11, 0x44, 0x44, 0x00, 0x00, 0x33, 0x33, 0x77, 0x88, 0x00, }, }, { "minimum (4, true)", 4, true, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x11, 0x99, 0x55, 0x22, 0x66, 0xFF, 0x44, 0xFF, 0xCC, 0x00, 0x33, 0x77, 0xBB, 0x88, 0xEE, }, []uint8{ 0x11, 0x11, 0x22, 0x22, 0x00, 0x11, 0x44, 0x44, 0x00, 0x00, 0x33, 0x33, 0x77, 0x88, 0x00, }, }, } for _, d := range testData { src := image.NewGray(d.srcb) src.Pix = d.srcPix f := Minimum(d.ksize, d.disk) dst := image.NewGray(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } testDataNRGBA := []struct { desc string ksize int disk bool srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "minimum nrgba (3, true)", 3, true, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0xBB, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0xEE, }, []uint8{ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, }, }, } for _, d := range testDataNRGBA { src := image.NewNRGBA(d.srcb) src.Pix = d.srcPix f := Minimum(d.ksize, d.disk) dst := image.NewNRGBA(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } } func TestMaximum(t *testing.T) { testData := []struct { desc string ksize int disk bool srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "maximum (0, false)", 0, false, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x11, 0x99, 0x55, 0x22, 0x66, 0xFF, 0x44, 0xFF, 0xCC, 0x00, 0x33, 0x77, 0xBB, 0x88, 0xEE, }, []uint8{ 0x11, 0x99, 0x55, 0x22, 0x66, 0xFF, 0x44, 0xFF, 0xCC, 0x00, 0x33, 0x77, 0xBB, 0x88, 0xEE, }, }, { "maximum (1, false)", 1, false, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x11, 0x99, 0x55, 0x22, 0x66, 0xFF, 0x44, 0xFF, 0xCC, 0x00, 0x33, 0x77, 0xBB, 0x88, 0xEE, }, []uint8{ 0x11, 0x99, 0x55, 0x22, 0x66, 0xFF, 0x44, 0xFF, 0xCC, 0x00, 0x33, 0x77, 0xBB, 0x88, 0xEE, }, }, { "maximum (2, false)", 2, false, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x11, 0x99, 0x55, 0x22, 0x66, 0xFF, 0x44, 0xFF, 0xCC, 0x00, 0x33, 0x77, 0xBB, 0x88, 0xEE, }, []uint8{ 0x11, 0x99, 0x55, 0x22, 0x66, 0xFF, 0x44, 0xFF, 0xCC, 0x00, 0x33, 0x77, 0xBB, 0x88, 0xEE, }, }, { "maximum (3, false)", 3, false, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x11, 0x99, 0x55, 0x22, 0x66, 0xFF, 0x44, 0xFF, 0xCC, 0x00, 0x33, 0x77, 0xBB, 0x88, 0xEE, }, []uint8{ 0xFF, 0xFF, 0xFF, 0xFF, 0xCC, 0xFF, 0xFF, 0xFF, 0xFF, 0xEE, 0xFF, 0xFF, 0xFF, 0xFF, 0xEE, }, }, { "maximum (3, true)", 3, true, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x11, 0x99, 0x55, 0x22, 0x66, 0xFF, 0x44, 0xFF, 0xCC, 0x00, 0x33, 0x77, 0xBB, 0x88, 0xEE, }, []uint8{ 0xFF, 0x99, 0xFF, 0xCC, 0x66, 0xFF, 0xFF, 0xFF, 0xFF, 0xEE, 0xFF, 0xBB, 0xFF, 0xEE, 0xEE, }, }, { "maximum (4, true)", 4, true, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x11, 0x99, 0x55, 0x22, 0x66, 0xFF, 0x44, 0xFF, 0xCC, 0x00, 0x33, 0x77, 0xBB, 0x88, 0xEE, }, []uint8{ 0xFF, 0x99, 0xFF, 0xCC, 0x66, 0xFF, 0xFF, 0xFF, 0xFF, 0xEE, 0xFF, 0xBB, 0xFF, 0xEE, 0xEE, }, }, } for _, d := range testData { src := image.NewGray(d.srcb) src.Pix = d.srcPix f := Maximum(d.ksize, d.disk) dst := image.NewGray(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } testDataNRGBA := []struct { desc string ksize int disk bool srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "maximum nrgba (3, true)", 3, true, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0xBB, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0xEE, }, []uint8{ 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xCC, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xEE, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xBB, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xEE, 0x00, 0x00, 0x00, 0xEE, }, }, } for _, d := range testDataNRGBA { src := image.NewNRGBA(d.srcb) src.Pix = d.srcPix f := Maximum(d.ksize, d.disk) dst := image.NewNRGBA(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } } gift-0.2.0/resize.go000066400000000000000000000252321513354670200143040ustar00rootroot00000000000000package gift import ( "image" "image/draw" "math" ) // Resampling is an interpolation algorithm used for image resizing. type Resampling interface { Support() float32 Kernel(float32) float32 } func bcspline(x, b, c float32) float32 { if x < 0 { x = -x } if x < 1 { return ((12-9*b-6*c)*x*x*x + (-18+12*b+6*c)*x*x + (6 - 2*b)) / 6 } if x < 2 { return ((-b-6*c)*x*x*x + (6*b+30*c)*x*x + (-12*b-48*c)*x + (8*b + 24*c)) / 6 } return 0 } func sinc(x float32) float32 { if x == 0 { return 1 } return float32(math.Sin(math.Pi*float64(x)) / (math.Pi * float64(x))) } type resamp struct { name string support float32 kernel func(float32) float32 } func (r resamp) String() string { return r.name } func (r resamp) Support() float32 { return r.support } func (r resamp) Kernel(x float32) float32 { return r.kernel(x) } // NearestNeighborResampling is a nearest neighbor resampling filter. var NearestNeighborResampling Resampling // BoxResampling is a box resampling filter (average of surrounding pixels). var BoxResampling Resampling // LinearResampling is a bilinear resampling filter. var LinearResampling Resampling // CubicResampling is a bicubic resampling filter (Catmull-Rom). var CubicResampling Resampling // LanczosResampling is a Lanczos resampling filter (3 lobes). var LanczosResampling Resampling type resampWeight struct { index int weight float32 } func prepareResampWeights(dstSize, srcSize int, resampling Resampling) [][]resampWeight { delta := float32(srcSize) / float32(dstSize) scale := delta if scale < 1 { scale = 1 } radius := float32(math.Ceil(float64(scale * resampling.Support()))) result := make([][]resampWeight, dstSize) tmp := make([]resampWeight, 0, dstSize*int(radius+2)*2) for i := range dstSize { center := (float32(i)+0.5)*delta - 0.5 left := max(int(math.Ceil(float64(center-radius))), 0) right := min(int(math.Floor(float64(center+radius))), srcSize-1) var sum float32 for j := left; j <= right; j++ { weight := resampling.Kernel((float32(j) - center) / scale) if weight == 0 { continue } tmp = append(tmp, resampWeight{ index: j, weight: weight, }) sum += weight } for j := range tmp { tmp[j].weight /= sum } result[i] = tmp tmp = tmp[len(tmp):] } return result } func resizeLine(dst []pixel, src []pixel, weights [][]resampWeight) { for i := range dst { var r, g, b, a float32 for _, w := range weights[i] { c := src[w.index] wa := c.a * w.weight r += c.r * wa g += c.g * wa b += c.b * wa a += wa } if a != 0 { r /= a g /= a b /= a } dst[i] = pixel{r, g, b, a} } } func resizeHorizontal(dst draw.Image, src image.Image, w int, resampling Resampling, options *Options) { srcb := src.Bounds() dstb := dst.Bounds() weights := prepareResampWeights(w, srcb.Dx(), resampling) pixGetter := newPixelGetter(src) pixSetter := newPixelSetter(dst) parallelize(options.Workers, srcb.Min.Y, srcb.Max.Y, func(start, stop int) { buf := getPixelBuf(srcb.Dx(), w) defer putPixelBuf(buf) for srcy := start; srcy < stop; srcy++ { pixGetter.getPixelRow(srcy, &buf.src) resizeLine(buf.dst, buf.src, weights) pixSetter.setPixelRow(dstb.Min.Y+srcy-srcb.Min.Y, buf.dst) } }) } func resizeVertical(dst draw.Image, src image.Image, h int, resampling Resampling, options *Options) { srcb := src.Bounds() dstb := dst.Bounds() weights := prepareResampWeights(h, srcb.Dy(), resampling) pixGetter := newPixelGetter(src) pixSetter := newPixelSetter(dst) parallelize(options.Workers, srcb.Min.X, srcb.Max.X, func(start, stop int) { buf := getPixelBuf(srcb.Dy(), h) defer putPixelBuf(buf) for srcx := start; srcx < stop; srcx++ { pixGetter.getPixelColumn(srcx, &buf.src) resizeLine(buf.dst, buf.src, weights) pixSetter.setPixelColumn(dstb.Min.X+srcx-srcb.Min.X, buf.dst) } }) } func resizeNearest(dst draw.Image, src image.Image, w, h int, options *Options) { srcb := src.Bounds() dstb := dst.Bounds() dx := float64(srcb.Dx()) / float64(w) dy := float64(srcb.Dy()) / float64(h) pixGetter := newPixelGetter(src) pixSetter := newPixelSetter(dst) parallelize(options.Workers, dstb.Min.Y, dstb.Min.Y+h, func(start, stop int) { for dsty := start; dsty < stop; dsty++ { for dstx := dstb.Min.X; dstx < dstb.Min.X+w; dstx++ { fx := math.Floor((float64(dstx-dstb.Min.X) + 0.5) * dx) fy := math.Floor((float64(dsty-dstb.Min.Y) + 0.5) * dy) srcx := srcb.Min.X + int(fx) srcy := srcb.Min.Y + int(fy) px := pixGetter.getPixel(srcx, srcy) pixSetter.setPixel(dstx, dsty, px) } } }) } type resizeFilter struct { width int height int resampling Resampling } func (p *resizeFilter) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { w, h := p.width, p.height srcw, srch := srcBounds.Dx(), srcBounds.Dy() if (w == 0 && h == 0) || w < 0 || h < 0 || srcw <= 0 || srch <= 0 { dstBounds = image.Rect(0, 0, 0, 0) } else if w == 0 { fw := float64(h) * float64(srcw) / float64(srch) dstw := int(math.Max(1, math.Floor(fw+0.5))) dstBounds = image.Rect(0, 0, dstw, h) } else if h == 0 { fh := float64(w) * float64(srch) / float64(srcw) dsth := int(math.Max(1, math.Floor(fh+0.5))) dstBounds = image.Rect(0, 0, w, dsth) } else { dstBounds = image.Rect(0, 0, w, h) } return } func (p *resizeFilter) Draw(dst draw.Image, src image.Image, options *Options) { if options == nil { options = &defaultOptions } b := p.Bounds(src.Bounds()) w, h := b.Dx(), b.Dy() if w <= 0 || h <= 0 { return } if src.Bounds().Dx() == w && src.Bounds().Dy() == h { copyimage(dst, src, options) return } if p.resampling.Support() <= 0 { resizeNearest(dst, src, w, h, options) return } if src.Bounds().Dx() == w { resizeVertical(dst, src, h, p.resampling, options) return } if src.Bounds().Dy() == h { resizeHorizontal(dst, src, w, p.resampling, options) return } tmp := createTempImage(image.Rect(0, 0, w, src.Bounds().Dy())) resizeHorizontal(tmp, src, w, p.resampling, options) resizeVertical(dst, tmp, h, p.resampling, options) } // Resize creates a filter that resizes an image to the specified width and height using the specified resampling. // If one of width or height is 0, the image aspect ratio is preserved. // Supported resampling parameters: NearestNeighborResampling, BoxResampling, LinearResampling, CubicResampling, LanczosResampling. // // Example: // // // Resize the src image to width=300 preserving the aspect ratio. // g := gift.New( // gift.Resize(300, 0, gift.LanczosResampling), // ) // dst := image.NewRGBA(g.Bounds(src.Bounds())) // g.Draw(dst, src) func Resize(width, height int, resampling Resampling) Filter { return &resizeFilter{ width: width, height: height, resampling: resampling, } } type resizeToFitFilter struct { width int height int resampling Resampling } func (p *resizeToFitFilter) Bounds(srcBounds image.Rectangle) image.Rectangle { w, h := p.width, p.height srcw, srch := srcBounds.Dx(), srcBounds.Dy() if w <= 0 || h <= 0 || srcw <= 0 || srch <= 0 { return image.Rect(0, 0, 0, 0) } if srcw <= w && srch <= h { return image.Rect(0, 0, srcw, srch) } wratio := float64(srcw) / float64(w) hratio := float64(srch) / float64(h) var dstw, dsth int if wratio > hratio { dstw = w dsth = minint(int(float64(srch)/wratio+0.5), h) } else { dsth = h dstw = minint(int(float64(srcw)/hratio+0.5), w) } return image.Rect(0, 0, dstw, dsth) } func (p *resizeToFitFilter) Draw(dst draw.Image, src image.Image, options *Options) { b := p.Bounds(src.Bounds()) Resize(b.Dx(), b.Dy(), p.resampling).Draw(dst, src, options) } // ResizeToFit creates a filter that resizes an image to fit within the specified dimensions while preserving the aspect ratio. // Supported resampling parameters: NearestNeighborResampling, BoxResampling, LinearResampling, CubicResampling, LanczosResampling. func ResizeToFit(width, height int, resampling Resampling) Filter { return &resizeToFitFilter{ width: width, height: height, resampling: resampling, } } type resizeToFillFilter struct { width int height int anchor Anchor resampling Resampling } func (p *resizeToFillFilter) Bounds(srcBounds image.Rectangle) image.Rectangle { w, h := p.width, p.height srcw, srch := srcBounds.Dx(), srcBounds.Dy() if w <= 0 || h <= 0 || srcw <= 0 || srch <= 0 { return image.Rect(0, 0, 0, 0) } return image.Rect(0, 0, w, h) } func (p *resizeToFillFilter) Draw(dst draw.Image, src image.Image, options *Options) { b := p.Bounds(src.Bounds()) w, h := b.Dx(), b.Dy() if w <= 0 || h <= 0 { return } srcw, srch := src.Bounds().Dx(), src.Bounds().Dy() wratio := float64(srcw) / float64(w) hratio := float64(srch) / float64(h) var tmpw, tmph int if wratio < hratio { tmpw = w tmph = maxint(int(float64(srch)/wratio+0.5), h) } else { tmph = h tmpw = maxint(int(float64(srcw)/hratio+0.5), w) } tmp := createTempImage(image.Rect(0, 0, tmpw, tmph)) Resize(tmpw, tmph, p.resampling).Draw(tmp, src, options) CropToSize(w, h, p.anchor).Draw(dst, tmp, options) } // ResizeToFill creates a filter that resizes an image to the smallest possible size that will cover the specified dimensions, // then crops the resized image to the specified dimensions using the specified anchor point. // Supported resampling parameters: NearestNeighborResampling, BoxResampling, LinearResampling, CubicResampling, LanczosResampling. func ResizeToFill(width, height int, resampling Resampling, anchor Anchor) Filter { return &resizeToFillFilter{ width: width, height: height, anchor: anchor, resampling: resampling, } } func init() { // Nearest neighbor resampling filter. NearestNeighborResampling = resamp{ name: "NearestNeighborResampling", support: 0, kernel: func(x float32) float32 { return 0 }, } // Box resampling filter. BoxResampling = resamp{ name: "BoxResampling", support: 0.5, kernel: func(x float32) float32 { if x < 0 { x = -x } if x <= 0.5 { return 1 } return 0 }, } // Linear resampling filter. LinearResampling = resamp{ name: "LinearResampling", support: 1, kernel: func(x float32) float32 { if x < 0 { x = -x } if x < 1 { return 1 - x } return 0 }, } // Cubic resampling filter (Catmull-Rom). CubicResampling = resamp{ name: "CubicResampling", support: 2, kernel: func(x float32) float32 { if x < 0 { x = -x } if x < 2 { return bcspline(x, 0, 0.5) } return 0 }, } // Lanczos resampling filter (3 lobes). LanczosResampling = resamp{ name: "LanczosResampling", support: 3, kernel: func(x float32) float32 { if x < 0 { x = -x } if x < 3 { return sinc(x) * sinc(x/3) } return 0 }, } } gift-0.2.0/resize_test.go000066400000000000000000000222131513354670200153370ustar00rootroot00000000000000package gift import ( "bytes" "image" "testing" ) func TestResize(t *testing.T) { var img0, img1 *image.Gray // Testing various sizes and parallelization settings w, h := 10, 20 img0 = image.NewGray(image.Rect(0, 0, w, h)) sz := []struct{ w0, h0, w1, h1 int }{ {w, h, w, h}, {w * 2, h, w * 2, h}, {w, h * 2, w, h * 2}, {w * 2, h * 2, w * 2, h * 2}, {w / 2, h, w / 2, h}, {w, 0, w, h}, {0, h, w, h}, {w * 2, 0, w * 2, h * 2}, {0, h / 2, w / 2, h / 2}, {0, 0, 0, 0}, {1, -1, 0, 0}, {-1, 1, 0, 0}, } rfilters := []Resampling{ NearestNeighborResampling, BoxResampling, LinearResampling, CubicResampling, LanczosResampling, } for _, workers := range []int{5, 1} { for _, z := range sz { for _, f := range rfilters { opts := Options{Workers: workers} g := NewWithOptions(opts, Resize(z.w0, z.h0, f)) img1 = image.NewGray(g.Bounds(img0.Bounds())) g.Draw(img1, img0) w2, h2 := img1.Bounds().Dx(), img1.Bounds().Dy() if w2 != z.w1 || h2 != z.h1 { t.Errorf("resize %s %dx%d: expected %dx%d got %dx%d", f, z.w0, z.h0, z.w1, z.h1, w2, h2) } } } } // Nearest filter resize img0 = image.NewGray(image.Rect(-1, -1, 4, 1)) img0.Pix = []uint8{ 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, } img1Exp := image.NewGray(image.Rect(0, 0, 2, 2)) img1Exp.Pix = []uint8{ 2, 4, 7, 0, } f := Resize(2, 2, NearestNeighborResampling) img1 = image.NewGray(f.Bounds(img0.Bounds())) f.Draw(img1, img0, nil) if img1.Bounds().Size() != img1Exp.Bounds().Size() { t.Errorf("expected %v got %v", img1Exp.Bounds().Size(), img1.Bounds().Size()) } if !bytes.Equal(img1Exp.Pix, img1.Pix) { t.Errorf("expected %v got %v", img1Exp.Pix, img1.Pix) } // Box Filter resize img0 = image.NewGray(image.Rect(-1, -1, 3, 1)) img0.Pix = []uint8{ 1, 2, 2, 1, 4, 5, 8, 9, } img1Exp = image.NewGray(image.Rect(0, 0, 2, 1)) img1Exp.Pix = []uint8{ 3, 5, } f = Resize(2, 1, BoxResampling) img1 = image.NewGray(f.Bounds(img0.Bounds())) f.Draw(img1, img0, nil) if img1.Bounds().Size() != img1Exp.Bounds().Size() { t.Errorf("expected %v got %v", img1Exp.Bounds().Size(), img1.Bounds().Size()) } if !bytes.Equal(img1Exp.Pix, img1.Pix) { t.Errorf("expected %v got %v", img1Exp.Pix, img1.Pix) } // Empty image should remain empty and not panic img0 = &image.Gray{} f = Resize(100, 100, BoxResampling) img1 = image.NewGray(f.Bounds(img0.Bounds())) f.Draw(img1, img0, nil) if img1.Bounds().Dx() != 0 || img1.Bounds().Dy() != 0 { t.Errorf("empty image resized is not empty: %dx%d", img1.Bounds().Dx(), img1.Bounds().Dy()) } // Testing kernel values outside the window for _, f := range rfilters { if f.Kernel(f.Support()+0.000001) != 0 { t.Errorf("filter %s value outside support != 0", f) } } // Testing spline and sinc edge cases if sinc(0) != 1 { t.Errorf("sinc(0) != 1") } if bcspline(-2, 0, 0.5) != 0 { t.Errorf("bcspline(-2, ...) != 0") } if (resamp{name: "test"}).String() != "test" { t.Error("resamplingStruct String() fail") } testData := []struct { desc string w, h int r Resampling srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "resize (1, 2 -> 1, 1; box; non-alpha)", 1, 1, BoxResampling, image.Rect(0, 0, 1, 2), image.Rect(0, 0, 1, 1), []uint8{ 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, }, []uint8{ 0x80, 0x80, 0x00, 0xff, }, }, { "resize (1, 2 -> 1, 1; box; alpha)", 1, 1, BoxResampling, image.Rect(0, 0, 1, 2), image.Rect(0, 0, 1, 1), []uint8{ 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, }, []uint8{ 0xff, 0x00, 0x00, 0x80, }, }, { "resize (1, 2 -> 1, 3; linear; alpha)", 1, 3, LinearResampling, image.Rect(0, 0, 1, 2), image.Rect(0, 0, 1, 3), []uint8{ 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, }, []uint8{ 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, }, }, } for _, d := range testData { src := image.NewNRGBA(d.srcb) src.Pix = d.srcPix f := Resize(d.w, d.h, d.r) dst := image.NewNRGBA(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } } func TestResizeToFit(t *testing.T) { testData := []struct { desc string w, h int r Resampling srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "resize to fit (0, 0, nearest)", 0, 0, NearestNeighborResampling, image.Rect(-1, -1, 4, 4), image.Rect(0, 0, 0, 0), []uint8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, }, []uint8{}, }, { "resize to fit (1, 1, nearest)", 1, 1, NearestNeighborResampling, image.Rect(-1, -1, 4, 4), image.Rect(0, 0, 1, 1), []uint8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, }, []uint8{0x0c}, }, { "resize to fit (2, 3, box)", 2, 3, BoxResampling, image.Rect(-1, -1, 3, 1), image.Rect(0, 0, 2, 1), []uint8{ 0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x07, 0x08, }, []uint8{0x03, 0x05}, }, { "resize to fit (3, 2, box)", 3, 2, BoxResampling, image.Rect(-1, -1, 1, 3), image.Rect(0, 0, 1, 2), []uint8{ 0x00, 0x01, 0x05, 0x06, 0x02, 0x03, 0x07, 0x08, }, []uint8{0x03, 0x05}, }, { "resize to fit (2, 4, box)", 2, 4, BoxResampling, image.Rect(-1, -1, 1, 3), image.Rect(0, 0, 2, 4), []uint8{ 0x00, 0x01, 0x05, 0x06, 0x02, 0x03, 0x07, 0x08, }, []uint8{ 0x00, 0x01, 0x05, 0x06, 0x02, 0x03, 0x07, 0x08, }, }, { "resize to fit (3, 10, box)", 3, 10, BoxResampling, image.Rect(-1, -1, 1, 3), image.Rect(0, 0, 2, 4), []uint8{ 0x00, 0x01, 0x05, 0x06, 0x02, 0x03, 0x07, 0x08, }, []uint8{ 0x00, 0x01, 0x05, 0x06, 0x02, 0x03, 0x07, 0x08, }, }, } for _, d := range testData { src := image.NewGray(d.srcb) src.Pix = d.srcPix f := ResizeToFit(d.w, d.h, d.r) dst := image.NewGray(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } } func TestResizeToFill(t *testing.T) { testData := []struct { desc string w, h int r Resampling anchor Anchor srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "resize to fill (0, 0, nearest, center)", 0, 0, NearestNeighborResampling, CenterAnchor, image.Rect(-1, -1, 3, 1), image.Rect(0, 0, 0, 0), []uint8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, }, []uint8{}, }, { "resize to fill (4, 2, nearest, center)", 4, 2, NearestNeighborResampling, CenterAnchor, image.Rect(-1, -1, 3, 1), image.Rect(0, 0, 4, 2), []uint8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, }, []uint8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, }, }, { "resize to fill (4, 4, nearest, center)", 4, 4, NearestNeighborResampling, CenterAnchor, image.Rect(-1, -1, 3, 1), image.Rect(0, 0, 4, 4), []uint8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, }, []uint8{ 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x05, 0x05, 0x06, 0x06, 0x05, 0x05, 0x06, 0x06, }, }, { "resize to fill (4, 4, nearest, bottom-right)", 4, 4, NearestNeighborResampling, BottomRightAnchor, image.Rect(-1, -1, 1, 3), image.Rect(0, 0, 4, 4), []uint8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, }, []uint8{ 0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07, }, }, { "resize to fill (2, 1, nearest, bottom)", 2, 1, NearestNeighborResampling, BottomAnchor, image.Rect(-1, -1, 5, 5), image.Rect(0, 0, 2, 1), []uint8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, }, []uint8{ 0xa7, 0xaa, }, }, { "resize to fill (2, 1, nearest, top)", 2, 1, NearestNeighborResampling, TopAnchor, image.Rect(-1, -1, 5, 5), image.Rect(0, 0, 2, 1), []uint8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, }, []uint8{ 0x07, 0x0a, }, }, } for _, d := range testData { src := image.NewGray(d.srcb) src.Pix = d.srcPix f := ResizeToFill(d.w, d.h, d.r, d.anchor) dst := image.NewGray(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } } gift-0.2.0/testdata/000077500000000000000000000000001513354670200142615ustar00rootroot00000000000000gift-0.2.0/testdata/dst_brightness_decrease.png000066400000000000000000000704211513354670200216500ustar00rootroot00000000000000PNG  IHDRxԅOpIDATx%u'FsWvIJF3; `Oxa٘x_hB Be/ăppcY{uڎ>M ""4/ǿ9;8x<ѝ/_?|t W)nX@5,?{7Ik؀~Z -/b#%Ik0 TPBjHJLnޛLf}?dݝ*$z[!PH?Hiz)OcSRAJ)41I*P+A*Eob VBGj+X t5jn߹}dřqbUk+W}U^N/b.FB$D Њq`~q9I66"'^=:{A38=s?i#OXF^9QpCkBI&4a-Y^E`gWz0<>$d"t yUA`S%{hQjZZ6-ۊH 5~ȄRRYo [!5F YIaӯճ…& ֯FӘQ`"5;~g&F߻CfS[{;=Lpy\j0XOD+GELgf6'_A62vOFX%5!fPtIViݣGRFz` w*9{)OBZ)#Fv" L׈S)QIi#I~QEлv4:UFd^&DF)jֳAB:yyyNΖ{Gw L민};;O>e+YgGf~5ﱅ_|P/ CO{D< v6Ý3m= '$ÆOߔ )1dttph<6þ;XPC +AAWJ F EС$Br)j١"LN(aD_l md ٌ@ 竩52{XN| :@.5${yt=_uo7}{?Zc%h n E-K/~m8\ Fxqtpwl~cfJoe*g"ulD@y3`*+'5xz0M0wnC$ 2ĠuD(Db"$ِK!BKLq_%SQGCn UD&HB$$/_Uԗua$bQ|<|)S$IЋyޭ/m󘖏t~)(l2LG2^癀a рBj8LjP x ܒMct~_^Ut<5kĆY /J[נ4=Y9 IC?- qµH.4NfT}V⨘OIJgDV* mOIL (31*!UX䍫2!⧟?z݃;'g槈o*ut$hys4q?ӋgL- ,D4&:cV a2գ1rDY-phA3F! FC.\0dܪeg`v`@Y` b1m$Ԋթkn+rZe d"[Г=z^h&!o=L;u]yޕ >P,`kR: GI-a`ʤU#Qd3)6B`ɸDHjL! !0ǟ|[G{'8$F{*;4r}1%G,BZ e:45/?lah` ZB1p NdȆemQjae?7~H>eڿW޼?eЅͪ;o.i!n \-{?ńv͊dm bF0K]6d(Aր= 'Ɔ"|- j T4ZXVV+jYYe0\)U(T7nMu\{ƫicK&,eٝh&t1($gO{wc @+mCI- lFeզKn~Z&RQ3;jC%jq@lZ %/}Ři[o H&WL5e%anvm73 e0&[ўV"]$Nѱ{tQUU@H[ +6`R@`z9.XO05֐Ecv+"C9]^)vyh% crf+oS&D !Jr*~ED"}N^N=^TW0ab LPdU9:a LhucN~yX{HY0-`!3J,.vl#d͗dp2",Q@0AǂUI$)$O޺7Xu޵pT6e擊O1dU] Ձ?qb4*$ L,B aWR"X@GT$`X7¦dwʓSHdF7P3 )H1%L PBʇ$N}i*T*IAO>( (iblWڐOP׃a3JF($4M$._\.AH)Fx6쏛MWW/_LR:1"ÈPaprw K@f.xrr$iDj2pOxdVR49N` QT#ۺ]$)5 ~0{av)oBkv {.q-(r&#(qH{.8i㪡k rLd+l.gKVZ5v7f|ź=s7F'J̰XB1&BT.+@EϧE0@QJŜXb1^rD RB%TJkK!uAQH?DǫÃd?;躶m׋}O4%Vqkn:͠;ڽA51ڸ;~N=̜ATK ۄi䰠RS'Nk)'qrkj~ݷZj3\.:Ja}d5 z O2J%L=dbkp>f5R҇PU]}v&'Ahc&Bb34v? )G C, +Ap ƄH还%d=IvETNL=H^SFkic%Fi6>9f5m2&{絽*nznvWJM3ҡpSM{d؄MK@+V6d@DI3S9O4I9$*D%BέMi)0u~T~^FAؒ"$qvdK@w`:;R2OZx}L((ڝ?TtwNd Ɛ7MBE3&l7l2<c'KR@\gE5.)UU̢R(!~E2pdcd<I*Z/FzwIvD@WeHc6m FD)Tb>)A!ώembb/FI~QlaAdVEJJ1Fk ؙh֐P~FQ!&cR$mJwnT Ղ;g K!!G2Rf9$3vt4 \M`BߊlZjc/ k'9T:J+>RF`$<+_yw:,kOTMԖx4FV,bD)닓ϟ<'F qVāW)su2S(_ ( xwV3k"T |ĘЄ~ؾ6r-#u~)S0l.$&MEFBQDmp pO%im'{EgKMA)_SkGJw ^e? d1FA%@HZxIr'90Z'9T5ʹpj[k ~߁s̀ܛJD4=ٟ΍F9F0Wh 9$ɓ閱_m]mo YbJG;9"yLZ[9"r`xJc9' 59@8\ \>inܸ[8~nyLX5ue5;:FNv@f&^KDbNmc *;R9&Œy3Pe &5z "Qp0LR\Œ6T̢҄~4pX`N1D͕@?>Qrx4&mߵa mnZ^BMOGD[KysaL9E[9ԑ8`*Wѥ5DƱlɜ;hg0W1jەlt>ylj#F,+S0_RY0orj<wc.\ryTmCj`Aټ88c)Ȍ׃|߸_=~Dgjjk:YorC؞ DL#Z ȡYO ZRTCc+|^(aZ؜Nc6 8,S[rW@bNJ7"B+y(e"ZT:9)-, _ňH(DTCPgwr49I4a eRYdXb\MFlTr_ut KɶA& zӎj[?RAp-\ =J$7B1p峓mSlZB xtыGH\XIO>E4rYB0`&áhb- e 1}1dŏ_}K~uz^z0jJi,'T6k8"2Ha$A+U%V $ @Ԃ9u1@ttS^ĎD@iKk)I7o!6I( 'ޝ/߸;@j #Fmr9d಍F\a,kdAZ"g+"r,Ck誦\b*H$N\J.L ,R8('v ,gd0r,D^irp J]7 fkcmm|1v)gSD1@3#m6O lV=alB3mf?;b BdOMv9" @Z& t֯}c+hU߅pA3nFT -X.Ӣ7€I1}9}!x+Zկ|}[>6-e2X='ΐo`$*]޵i2#sR"?,l hE$1KIqe0ҥhȕpzU.uμ8ե,4"gї2St?"zhvGA0찒1#nٗ 㮄 7"GjursDMJzGˈ[L%NPjAT\[@>E[P:Fz\,`2>1QW1*Zb]R)R͍3e޸Y&v-)Mb&gk3eDkɄJ$dxYΐT g'W˼ ,L4`f:=x PE HᢸBUZPHbٛk5*enFe,ۉ末Q*JsT\ӬJOg’GdEȤˉ{"\Adc)%OFЦ$sN(mUrXmkYգ;Ǐ]fNsȊçX* ѻӳPUnj`, E*2bZz)w\JfaRql9_܊HҀT\֑8Foi+kFN23dy\Y=u\"r[i9߹nY; OrZi5r2Wde{l$gU8"K6'EH9G'M4k>0ÅANKy-M&:2Iksd,"hjONo+pcG}*bvV;U |vXk@ҥOBkmo7zq psoRrm$gO'K|OWCuUUJm,宻%mCd&U3*U9ߒ&wP\%\d%8ǀї.\X'r $ R9O[-e%rQ#Bi5Μ"L!lgMXZN=cH)gy,M`_=5ХeG#e 2"O]%,2O h[z>z FZ11r_y.aO,CbtԾp@Qt1n"*rEk ^簵HΚfL/ֹexJ>1冔T3wͥMYȗ3P.PmSltp`˝e*ŕlgjRcHf_U $fR%zk5I&tсBR'g.ڽmuÍ.xkz88yA<|l1.(W\p,%,8Ņ163Ig vZйj 5*X2bpTB^.V5cdyHa~ro Cߩ]bM[Eg0w+1H2 B&Y/m3nCYAɶs]i~%+`l7 Һţ[/~`R/F={bV.d1W1ag{˰!n\ H2lKǍD4r!u&O3.0)YX@k{8i.*)kX[L,ܙEqKgJ$0jъUJl]!Z "T4}!&pX?Z-)lG2bNC BQb隧88&]HS~ fϣd\nԽot8&*B\,/G  yǔW 䙰Yq@9yN#r(v&( sʱ)-he*e*!X8\WYf}X+s:+`/rEvnJ!^€(]2毂X3 UEeX-m,-ԳoԤOI8wpی&}\t[ypBJ }{[~imEm깳tu(Y;oܢ!-Tۤ:??[>o 0}!ء@!zCm>k \8VUh+ٺq&r1kPVԮ.7; s 8_\Ŭ!sT_’K0S2L, .еU͐'~TR!K# H Ů2M]i Y`85} .z8y3W*~GrQvnithB\ZSߺ󳇫_2yR7_;Ҽ~N?[BdB81d:iFjDy@) 'G(v!I;03t RڒY .%>cխA&<NǟLvlʶ镯0vmF4MRUa]1}Vm%nWr`Jj#rV_'̅K 9Ç`lGz!Yٺ΃vA혍 @9v1J5= l>ˊ}X`zOKS!:NN"\YsZK+ke$ggObyB@`4cT$Ed@ ߄}#r)/=Grn[>Sp4(eDwhQJQVz s/qg4]I9a_ĢIFe 9s[|[ub7NXu4o%N4-\ +O[AQO' i6I%[1H,l<R!կ..ݓH˃'\Q=!VVCIAO.*z97/ϙ_?2ײ(L7 }hRYYW=:"LBs;d7Xz9,d$TȂ\#}|ҕnx0 uFn _L lC(3^6˖vd IJ-\5sVqMa-N!mU ntBi ⬱\^GmApx0@W6T-w>u=nfHR.9ceH-qu Q,ꁨ}DT#Ux28RSD{) [?7RVI Pr,RJ1%6gsIP-9Rvnt߁Ջqߌ>~X՛o.{"I1 Zf4bRt0Zrc"Bܘ#*s!m-\lT2q$6+Qnw=#{* )?%3[a7'*RDn6jybmp}Ջܮ7GÉV&/z!=Z_I .WWv6ED!MSXiOL5^B`!y,ܾ?avXps ]2y/>:1iY0[)+@ګMURͰYK6Ymu15g ,XY)#3"{fRİh2h-ZmqZQa?nu51J% -tp~4|d?@n sqGZ78 ["\r)}r]6>T,IUdU.ybg?p;iMN&Z/#ٴ+';ъҌPEug}pw`'`rB)>{݋GN^GcX[[u3#|-ob]mKdt5nE͓<@_ڹՃ]%9#d[E*П67ͪwo6 m6o?mfG_Kɋ|`&w^#'hZ4Cz`s̈́:i>FRb9%r fciQ2mWF,Z[;a3mF.\H*SU68WW B!L.?XlB Jk7FRY(dp>{?6&@֛;j(uO6W0\!ϗ򜳒Ujq[Ι1v4VZX#-FSN*xL\jxoLڿQ>[ _qexHjW|9ci!O>]~^),ۖ6?|NL$Xy^FeC_ˀŋ9W/k C%31ޑȻ?|w^_>}4;@⬏]B]hq!K8$ \gWnZ ihuܸɥ\ v 0W֕s5?~X&pm`7JV'D DjC߅~^K/w{*i3npuvU}YIVDmi! >$L!ςt" pDx4`Pm嗾L[ #EM$_̞Yaf*lR9(H?o`@^{a6|(SNd :O.L:Ri!țC(@  ߪs"hJtLQSy*P` c*dփ]XlRmv3m&Gİjm< XC퀯܉{3D''wFlͳaU° x 'U]]Ov?/v,ތ=*s9aL.ѹLLc"7>:w-4;.DUTZx_}# Nc½xxFp1`f&48GCF|LŜc3}i.d ) #P\"!63VW`l4,AP0ֵTd {{'217A|~y@-=>`?y \w[n0rg>#\W⭈yܸ4?F5+W?8\Ka6;NU$qƝܐ"x돱FD= Pa8D]\n[\!^TRW|f7Ӈ.}./+q %z{z>g2Jd\= t=G\БJ# (#6D%UPA%ycW ;?ޙIݳZGZDx=Ban/}O|xǏKAiR൲'sJS̉.F<INJj4݃{K \=x9o39-vo'ߣ#΅ 3ńs(X80<38_ Iy$eYM%III%Ceۄǧ1 W}{]]B$V+8ޤe=_yR]N'ɫ5Uo]}xcs&~?*?6{Ϧ+Ӟ|_'lGV< N Xs Qf̴#39{'>ηPR\*74$|B@O@.&O94aBO3FY!߮T 0tHWCAⰯWGW{뮋!9/MBI` ;m5߻19i ,W^M"oj@ ;?:TcSs&)C<هagYv9'%JcE=v<N/Owf b\2VODZAhm8:I.xcy]sQ#8)=r!a. !GK)pD FWG!BpB:̓s"oɇ{ jWC!12Pyޤx\>BЃs(~tZ_/~}>-޸N% k(#g Z6k͑Biz$hѳg/ί]hL`@BGIJ ыLoc@ZXZc}&f}8__́UFl`It{w.Z&tk6sx4AkT5X"%K>%l,a$zru+UA0TtK 8ǖ㯸,me2`ah./*wxmh G7yz%= ?{?}^7+u7ed)jFHOMH=c ]IqT)'%QH:I|#"0vԧt+I'H 1 `|.)9|[GUU FVF(S2`M{J6Dex~qwi%"P9DVH2s!cswFIj.w[0;moɧ,N~/Ǜˢm!^3_mʎX mDod@TR2w M(jĸ)NM"@I0l3\ Gm `f9, ֡_/غJ iڠy 7,TZ(DT!XȺvN~/pFN}3(Ac D?b) .bx\'ab]0 "kx7 L1|>kw3lo|`}չ@`V [ESFbGE\W$VQ"HRЦ iC qQLB'JZCǩB IHO\5V7|=ĆEWo\4E߭c/WnX<@KeZ2A''oCmBgna}wgC}~7C0I9^i2 {Ny>_kZ$&tuӉjog~BaL_MMy<Ѓ?o/fyѴg9?-":{@~OݡOPw5?_P93_څos pJz٪ Rr)-)a ݮiNvy?:&\##ƚN|Νyɟ^~6P,nwοsΧ$ei}CeiNi.U^.-؟~9xB'G6iI[BՙE6cɻeI5־.ek~%V-?ޝ9et[M,(K;wāY|wj7ψ]\WPθ w΅q! )JlK=n[0z1Y>|WVP\&VYyW6 BDiy;Lv[Tg"Fc ~KƮU*y.kKR;"YK-0?9MAwߟ^':4V|{w?O;ŝJK1R|WLb(F#-55inn KBHXWC8{&v?A5|c[YG= '/>}Q |ˇZ#߲G2ϑ;jU\kK3${L6BK;X8)jZD=52Hm^" g-:h3=Ia B *` 3BQZvJMp}*gX/5yryVOh=+ 8c7RY!8޼U1eT2φPΖ U:TgI$KjV+6Y=W4Ͱt< XP( ݁a+|;4mw**m'lҮ XZ%g7H/A4%B%Ÿ!Ը߸N,6 /~tv+rFP=V8,Um%1!Q*WW)k)wvA |;iYs ˛H@%H[QGlAb MXC{T'+D~㕵'0Mʃ.[>avR'/./O[…7'Rs)U8iQ)>6>HDkw|quDfJK>3E-c*Lҙc 2]&H@6$tn:eJ!cZ<0VxHnxn:2̑v;ho3UIҲkhܮ'ln\'%pH]Ay)Kp>m q[wÖKH8TZ!eEyh0x2! &Ϫ6DТMQ'r@nR&Kz5O9;S$nP wma @ ~~P5߿/PG#I&ϡR6o?H7(Z?SVEbxtr}trO]yCXuv#E[Zfq-T97WJAYLYj7TS6AftP .N NT.:V*drhB3v9Nѳ:臨2lrHSj񁣟<]yR^c܏=heL tT(J8眷R[n"UȹҚ>R ZիomHXbFoCԼ &1iF%U(Ԭ{i:ɘw>hHT:O_?B{c ZkTv׼f1VM~.]o:C8/9~}ضPMtj)RtL$-i+쥲GϳbE(A;@ ^>ݹsr|W\$!y^v[JD[~2rߺt2fٲs9:W>cz=:=:]}ZA ߙ"<5"ϸlX8'\z6tw6o8ruj\[;^:F `yվfծ72M?:h-}eGm)ոt$S+BT+MJ {g!u˜]\%lT:[8yQeλ6eFzlA)wEa mb/{SrM<Ĕȍ](~:jcDAi,?֫Ogqk%\nݮ,T2|x\/sRuN6]+G᥶GQA4T"fiJZ-mљL j[FWRkZTt6˰bņsBŖFu׾9WOv#ebl :4+ƘڗgOttʕm<Wj+j3 r )@lS@l (^dB<,K$fhG0_WS3;j}$B:P1)pzedhHuն0Af>u^0SpئSNZͤԁ ѻ (ٜ" --RwH42Ac%C+&@*o>hػB̥7u rϯhHk~B"MQ3YZ%*bmp5Z9"$ԙ G-Gpm9Ö4W-rG2)ܨ:V(JcJsV깬Ub%4au:mr07:|$Z<-tӻR<$-;buTn'2:/ A5guNީnv 짚@g :"D5: vק8Z#gnJ!I REًkO1 x65=ۯ2w=o0-M*թϑf${aj Jd+7`fTSJKY>,k=ئ/en䲽_|~j~,#}B\g ]- 8'w At *K g].ÿ(x!qE@<Ҹ˿al!!Msc vTDlNZZv^[1~, Msʻ9Ly.5~U3VYD͸P6ACk-ԜjR\?R6})=y7& Y `pPЧT bbɂepU5jQEvpX0USu~d=3ZjޜR 6VV KuCe/Qe1h%Ʈl>8{3-j"!Պ ; ~';߬OblZZOR}9]lKrvyVҟ : ifw[m9CUJ1r^"#!0U+`Gc'Gjڀ XEX, `ɪwS-ṷ6-h; 芯PVgn{Ȯ_Ğ/4@`)9`.tqX)AB m+,c@v!tO[Z8A7r~)Ʉqh `c*B ):4S!ƁՒB14*#95f[~0ZT)rTS}s9=DIMئĦUo/UaU :qNqvʳ+Zj.]G=*44"ӞhK6OJbN ε*ĖUQ:4CHMR@)ZO޳7q >eghD] F5زyU/U743=lbA thhMl\i"/ě;nb,Rv}~GY@F#Ҫ0'{7VtDA<[:)"PZBjBِgGӸYKm%$EMe/F?FAeD0>acVեlB[ƨ̺Z5/)psl8睠$Mrp:EIϵ ςxbv:&Ucv[LL>:_D\7̖F8($XG"\K> 63-QvE03"MOHR*8dNU(i9)]_ꬹ cǡuk#>U( i^uBF_(RGO=:OotڈPTNYv-t`/o` 9PHf&f4AawԾPqƾB•*1>Lȵ3kW|}BȆVS&1M w<S=qTTZFd(/h@472f{掾|Yv; :C+Osrz^j8C4dQQL?;Tq.NՖ+h'& C/sWR \]Ro, $\hv @Dg߃Hlk@PRͨ<%9+GC(zЉ_Pt_f i{b155!>YOj͇2a"GhY4A ܘ5WlcNzW1s.i)ui)|Aԫ鼀cyw>c2˰- rg⡪)KN( gMYdh)a՘`ܤR)|WQpMlT]Nj/4?J9TJN9%xjʋM]hJ0ɇ)(X\_! \( ̳G,{ 6JZ!w8lKW5o,EhQd8҂>`xͻ,#gXyp羠o# t0! ^TTr=zGA|hk>si_PGUƁ.r:Rmꦌ` .[\2WK Z;nr[A@qXMtBWuY4u1T\n"\ ?,K {6=!:)ulB(Cs`n د K2V|n`fža>As#XkKq@PKKeMŁ3BfLBvd2Vqܐ(cm.j)Z\E,9RQmڗ ƗƊhRsl*/D1ia>U? ش.XL+ &V/.p2tRb#c^Ime}FF)/"F"TZ(ɵL!S ໔v9ݤ>r!\r+e Lrg" f%?t{L^C]92c#ִ,JYUr=} +t"`@qNNEb"PyĞgۖC][Bd@iRݜR{rx[RLtB6x5@ %Z۳+[X /1ۈΖ ^~oNggOr0!ځ^(5AgBBrE'8ÓʔB&^6)nU(TFMG@LDL ҷ(8B%bmbzZG*F悊LOZ %/)iZh[a=׫'a Zj] p+ņs7{^}  *pC=r+CI[Ce^|O8X9"1Ň`F*̵E+W}^ȧ#"&O._{gQ1i{|{=>~޶+ DsFUUvP2% "D1h34CJJ.6]BiѠ,t<ޙ|<a ;/ Ƅ1ARҨ@Q2xq06'dQR*R2TJPҼN|2.m3oZae@'M>dQQ EmȊW  _ȽCVXФ&XoƓpy|)>yν{VV[uWaiA{Gw@tu\4ϗxut7=~ٙ-)^b~ L? |K+ď_[#o~Ֆe"D,->¤|ڢX ?wwJkNo~ٝwk͵]ίM]B:jkwofPOm1^ h/vkBæ$&$4F I-Rt~OAV+|1 BEQ3޾Unȕ֖ź(DaK9Ce %W5Jk9SBA.OшX5?4`bӢ,&bpl=^?Z]h:eCo|x$B㓹t^ݚTDs+T~`7GOOOݪ Vœ˫ukbk5 :;(Z yq>MLYzHΥHV */GRj:Gb"+|A%bĢ B{O!גW]f|_Eka )4 ?JTV˪Y6gWW)Er>7Jve,?F u6:%u~FtTJY6*/Mi/Qtse4?lLQ\cңF|!Cy<=_^;ؚܧ^zgƏ׀gBv=ͮJg-i -E!EК)z:N[ۺ>uhScˉu[;wlv|q}B!e ˪+ĀP(&Gч|LB2JYv|#lQֆX+@)D2*kpxȺ/Nwj(v"7K>gXHkN k-϶Yؽ3 2(`- >ld@`J;9 uՂ W{{0o?|a¬Fk+@DlَFngFalU#x^pz>JcQeYڲ%6lҳ>h[% eQemLU [[7Fӽ]غg2!G0h>|{`8޹b*?ID4A@| R2Je뢨). 9Dݐ]@H@+){`(*l=x[3j NQ LD0_" ` ? $PĤw̖2&R&F0 q0*݃90PV{ȍcQ mL^w.G7(=u/12BU|jR=0UKFE"v֍Wp:><ؿ}w.US'C.-MRx@t)yYMǓ{N9eh"(u|4Ԋ%5P#[ڲ=к(D52C4n^Bؓkz ʖnu  blF,XuM%$!HFLb}10%dP#; ɸTG8,+Bfxѧ?s^J>]a"Q"\iQB)Rؓw:w?^Bc)V)&^MBl jE ءomWp-G4 p4*c杽z̖ Fa3dvM;pg4غlIk]zօk:_4vX\*bJk -b,Baި*(e Ie{yKD0Vd ){)#&HpR8Cy2bS`كy\1RDȒľŌddآF'SHX A:,jCföC']{G4֡L` #qQ4/+МԲ`B{7&"b=0q٬2;7 VĜ"PY׈Lמ1BHq~[MlOoۯsv``kPT5xΕzF Odk,hL!1btf>8jVkL vh/Jf25BXo={{zJO';G,|)CoHlQNB 4~~. %ΫrTATdܯs]"o;GѮѥf (#1Z|32ؽஞ}o`hU]-y)Ҁjؒ )oXżQA5M [TٷCVVyd$h˵`:AYA^H0bIT$=&LbE׉QB\k袖OyB۳NdoA@]1!Pl 0`{Ʒ٣|{dI)e˺F(xj51@p?$$fubpOt7,dAeˁb9@pȆ\6PtذS29o>dKb.L|:,a0S܉XݝnYZ3"0CʆC< Q*Q"I3Q1bL a ⺁ש4V3ik+SZX|η$*B; xdD>=unV,J[S @ $Qr)ڠ)Lޡwt~rV5)Q(^P%e]f@xj߹Kwk|gX~ ͺdJkhe2kD2Q#h{[m4 D8|dž' ю=U p'P{;{;7}K_`,dM%ŶMlOS ēgO-c:xJ[v<\wQ$#CP)3U|\nPV}*\붆aI>cHJP0*Iha\xqzQ+Zʲ՗`ar&od5ƀ*C VgߡRÝrzp}BR$p$)TJ1%bo1D(ᓂ@V6Gy&ĹXF -. ~5Z)ms&L3JQdc7WF=$BXVjKrqqkn0 q|Yё:ъ iqȝ%XMFe Dn `R cNDkhвb$KvQQIZ76]~ ccfIdӭME6ȫoyMTMRQ/lOvuUHLs>2m`Җ *6=4 kTD2`S[hDUTp4ViDV(>5-ʊuάRv{*Gs<4{(ýn#)erRi7)FP Rv Q̐I 9 GTI1 kJ[Y"cRQFd Ue Q|vLtnѵU4F}% ?_bD"p A_)0ńl)DF 9$nsx{:=%3:!bküJhǘ:,EYTBV˻/uZeU8׿r;q) [EQ ZGNv.AT#`ɡP@*H,DΛ fK!3dΡ} R#qkbVR܆--Ei h>Gpf\@5StA=}DʷizC:x RG{[0X&IU! 9CWsM:xOx @pzs% *+:=1!)1J`DF4ݸq eE!- ne=eM0Lɒ#BN13}tp seF_9Mʢ 7q76Qr$̟3kyl%e$t`?1fWy%,|X>Am̾? Km0Waxrѣʅt4[[C{kZ`ຉ 7KI[њ/ԓ @ʬ]~°K>ŠTN`"QRR<,lekӽ1F=f0w_VPluqQL@}PFlX$!h 3<%?[\S݁Mɝ^>5br52o- l.ޔ&J!Uf5:>:8fy*$e"9v<!%Rr1ÜMhJ)K0VkL" Tc} V JQ%xٝG]$!4D*}LΙIP$&;W>S;{>%: (RLhRBUV 6;l^]).*k@\泫Sv,R))V Db</aJT'{OԧlHxr7P-?^AksR1( 2Q3(*FG[te"Hi[icua*71Oh JAYI9t!7F%OR0DzvK0;:|}p~~vbs Yv4k5Atgo{o0@U=!7bTBRd4@ R&JMC8!Ae~ >-1⏘?HDϨnr<ԹM +VxXF?-"!S%$9%#WѮ^]qšd) W魻oe#5r].DAAyfAJJըH-'ǧ@qw=ޫS`#DB%XDHR$Z[Z #_H@f]WdMbsMeJC}̃F4i.2HX}AoZ$uTfRi+ FjJ ΉOp,O`{KF+uQudX9\rH1?79'(o?vCFҘ6HrO$]hRnB+] .?}ܬ֣t_,Y@&j(4CU ^C:@S; {AgA*"ʦ6.A ձ~\."=Co4 !"̀)/RrZ~$cqs=.κݓwp l(:n Q9^ZUGM E8+6?1!xF7R"HLK)+/>NQ?x<'%;EGo2/Mu_BH*hcsIێdUr&4MىFM\XV Lkvc-7Km)kTn20w*&9i0.v((!8$@'&@T`?גCn:k4-X~Q6hX ]r߉ @TX̕ZbR`%YR빙诛Sy' Hyj-0sބfl}N̴|a/a`J0Z"3̏F/՚,>E+Gb(Ksq~rIL;ιպ[4jX]QhG,!_D6XA`'Q')\2v?V$\k3B+ZfOڈh*37Rً9}E>)P"".\X9t"̕(srkrj^)!,W[Pغ;;+ 2BW=$p\-QMxIrPcdCWY\jqCыyb!WĘ }ၗdƳ5}@`t( @?DJTsվPJE_r߱λ/3Q 16֢S VϠUh JKkP!9rQZu'g˧7 IoºlO.ZbBd'r}zrcX,n)JN qڎzX]NʁSmB"V1H-W[`{L!PP/Lf~n;=#~;lb4%q/aƌsO@Й͕dQ"R%%k 'zVo;gAb5%*|H[{f"n\#DݕǵJjJ`aQТ=U?;Y)1E?kLMݽݽɠcfL^گ5\.[v~=Pj0~L/w_K1{by@ H60} ?CvWU{'o>RM>6#'at)J%y s^844)T>R`TJYJ5ʢwF6FQӴQ+0 HYЃ}bF̍ 7*'U9ץ ([ל>VJϮU$;4MEhW/s6U/.`Wb;:$XHςƜ Dҥ/JT:ʝꁛ8Mk̪'`"I>& $ #ho#%E2}+EI*O(P*o8%7dgd7ޚH@Ǝ:墛{+?׶P(.u9(m;*5da%:9:mqYԵ.V:Dw1{Kd5 بJѮKX> ع\T<(әVJULБH1%3OU JhY˺)6EH1^(Ab1<5*UA mn$^HْR1mS_`%p*Gf?1zOB6)uWxw\R" Bg>GеaF8t;Az7`*a=2~JZKJA;&̎/>x42M+R8{J`C$ *IfV̜ "G.?ar/[ %CCs,DcHFh 2&N2P*( ) f4 irK'`=/&!/ Kf@.4"EI W]:~/Y s7J+3%QV,o)Q\ }?MYGCdE\pģn~+kxEK*4)Ȍa F$1?yTFb6Cq糏+XI}6Ri e8a4dDC,F ZVd;z/U]E=PBr>.첼 TyT Ps,R)BslҕcT?"E R9A2 9t5ܿOç>{rDNRy DR|3FIcfrg !$2GIk[S$TloӴر+&݋ hΡL0<躧hd~j-p5"O}OŘT9vbɅ<$IYi(g ZYbDij[ bԚ1}4~)(|.[YRPځw1aH.6sHFƏ= ͣsIJIFRvcxS=^J{J_߼+F67 ?`0+\MRi *dUPmT(&2!2SKEhkhL4Yz'kXXxf-=g3;Ox]֡imi u=8G![v!RP(iS?ښYe U:RXrV#k ub ȎX-HR{$`<:8-R젪;wÞu,\r| L='.+J`SS0_Oa1d~LדwfS ˧Ӻv Aj:6j>'gotuI#g;w*@9!G߾g"a%UgTa)몮G [ _rT*$+SPB2 PXaD:b8%C]}"c:{˴ad \ ]xPpr `py {>lB1d0`(ŵ)+ SOSO%rR &n?X,m"=L5p` @Ǝ_-Ok[56V u>d˅D'GwP!8E@O V'#4޽zr>eeRKgpQE5LUҔ0:5MJz(l2}'c^7{/i}$ 7~O߃%فWځ?6 e|a 5P7>h@@I1ωd2ˇYj!RK΃Rc͑:@V%sRY#>]#,Y<r , ^3և.JY0=]GyGmL .%:sMnݲV7Z-3[oݒ.<q?BZTR'%L%6Fj7՘~0@nKMaJʲ,=D\\m:B >_C; @*l!AM ׿%C#Wq.|]ؿ^c@zY߇7~DZ2%3c1Zd6O cye oKI2F]JsEԹ V* Fo&G` T=f,FOIėOjv_5A`|S [ϮJGФ$?m@~Ke]PP$p篌?- 0E^KncV?s啒 mG߹\\~~/R]-t|0uH+yI Q>yP ɞZ}{ vp۫{oLQ 60Sl|'7;g|a G ~S@ZΜJe69O. e"AB\.֠" $Z`@4+;ڂLt0AI檢>cwQVB`\3mo۝}F=E>wâkyɘ%(޿_[`(K@'wǟ*@M~bVt f2O)6h IwmP6Joq՝z7gǂOB뉜R)ShGb.K4}LwE1vY|`$Uy8KöHvJx/$mjS=@ݤxNGx6FKFgKd$r|p7#1d1~|vڂME(x6;#_l+ IC$/"yS 6u. M ϮHcJo`<ɋhR৑;޳\qv? nќ=_==ޜ}GηP1ɥh@Z頃(J1#$a=mW,M\ \Xw~bY>&%q{vvEeubwiY]ॗ (~[}՞_?~oͣ#]/gu(P*@lw.ͦ ^uy#um'W\??$vnih3"ڐ'KKOԲd)w9hf]=\bb1vsh <f.25>/w!,HЮ᥻ s;yK.Ow!tcB{1*ЂT"R\$G*BZFe.aH4u"2b,*8]!ҙؾ6oV 7r$>> P11@ o9 [͟wNuջr1snZC7vߙz$gH)DIF[ߡ݆k޼I)E/Fd?Z8;%F2Lm =}|p.4lBHF@&!塾QFS.u _(*a_-Q($|4b1 6%SwԹqTuT'JkjWq}uz}w1u~u/T??O6kIvxgg !O˻qWB}kId-!>g_^Fߴ~֎֯n^zk`uRdБ0E)tՌ=~p:+i)Ԇ]0z&gi+z_%;[TcUNre*/f.d?#d&d+\v%; ƾ64Oߞ12PN22+J^TbFLQR^K?0&"@=R-3[ɣSw@^1Gaq}uu[᥃r&l݃#8w`LesQM|\ҏďtvo_R)\HˮbHRf%=YflSWI d(3vzYIdfݫ/s%CQ h z1`0?`oÆa%[ JHrf\g2wDc}kd5=UՙyXB] *BBtdсKj[m+zRpc'iD9ƤE"#6%jvɦs Cl6]KFYRF|thezYhh3iL1U4.:Wt^~JK7K^O;ߤ#?'p̒ qiFG/: ܱR9]bJʶ\tL62,FNs C- $Moz V%[kok!<%1O3n˻S≿W϶?uy[CA@/9~F[gwzv{x(PZ+2̔8AyP{v(m;g/CE="-J 7CvDL r/})Q "6PB Kc܄G/'}EJϾw0ޭ]eFQV[@c~c~3ShJzYXJcJ}ce7N?4tn"?ȗ-0HO|vr9on(k'So/#,e.gY~Ɨ'#HkW\`ԇx u2 7á2z:4!1c" V.>'9_`ܶ_:Yox6ℙsc}MW6^i%=_~9^e+8N.s(0*vd&TgZKm[K_kuc叩MpL}y/'+ //8}cjGia{695J[V)kk[Z0jPUNk۷0B M K:< &SSk=Ui9Źænݦ,yQes᝴xӛihq&}g=ԍKSn^"(3LJpR^p8 N$fmFh[XV7DVs/Hc:MG:ѫ}H}Կw_?*о9EҾRZ/-mĄB< ^A)*L2.enu4}Sg/'֌hdy!8ncy;b6֚M(fz-kXÂbd\3 5G;(zmpzfhgۖBz~'/2-('Vy?=[6yty6A.Z%H~`(l ZV&(O+/hS>]=z]?ŻF9<r?ek2AXz'_m 'o\2L&lE0+7'هǡny]Ź0V sX]lt`j 5T>޴dl[KK 0T%R-o2 ]V_jO_ X=̧ aͱhja>·SWbk)󣘛RoVmtlLXonBqE^NMBGtxW , CF/hyq CCLE ֩>7'1fSp7rPdXjN1m{@14B_}VAÏ:Y4j=l81d,fs:䗣l=DWV~i_ۻsIRdybPsB#q|wVIܛ&v̺Ř2Fr_n8#cnq\YBwm[+NG~qsVѡ#)O%Hv4,>pǚ3g{ c2G.yw-PZ`0ZHҵ!c4c5 +?3-':8?'P?<:IcsOR¹oV@g:]*1su?0vz.B[PkXd꣊ec9pڔ`x0LƮF֖[%MǓmu@ ?2V;Kp>҆vͅd]1'LzytEtE2}ͪadl13e~gv:`CPR.cDM]a6hƥuo!h7Bx߼ke|~)M\G}mR^?9ڷ)a?QǞYEgvp]J[[FAr\ȦV.O{R6-+笛U 8$LP7vB$mK:EZV/we:p1:ZgN#=J·Czc#~`?5moe †转|KG3$CqfD'Ĉ} }mXr8&@gѸGL.D0FBhlW5@fj{mN9=}x`=ԯ=. _ۿ~a%\Rf-UV\\NMyX!m**`ΈeVІhkkYjkMͻ_ne]k9aK9PF9FX(Rۜj,5ז'Ɠ?cEnbʡׯ/˂9y)):^00v~|`+fcHw3,$42%OCA (R_J틽ws a;fVƯ c<,2ߣ|ߏ2mYoz(z늘Em|B~6AfH>޳BFܣnF-?weٶ &&&8W0Siҷ)e SMntzO_wE@4y!>h`6<mbI%^#JA 3v{.ݢ_+mm)}[jݤpӉ,02F 6IZ7!6ѺByQek7k}8>Q Z&Fh~,{"H:Il-0M9Ni>|#79QǨFL'uaBy± G1G^c)g s-V*gGٍcjYBHfE7oc}N6 Eg-TJ:aM,|Zz>1b``5^:\lYPW$0|}YjLoe# FusxtG?])z#TX{.W2*6`4;Dз ^wiH1 $H=]a=Z8N=S$r~X 8'O? ,:"z MnOÔ4_McfCid6iUO-}򂅎v"d.w<2lՊ)1fA$tsaazv8F,zJ43Ӱ,"B;L84inq sʒ\\ՃR|؁/kKmìP$60O1Ӛ(K}k'/_~Ϟ) ږ{⡔|xi>Lt=O'ym B6V((&zN>&2fZN[)\% p38wǑA~4ڏ^dZ>_ڽ%k-mԀ,&iH㎞_l/mj 77HgRj4rEWOt-w@#+g:|1͂?X5\ryXȉI %0 rm^>ͩXM19X s$!S|8L!c'npϞ>{G?}yL8X -BL&_|r7yL}z{ێWNlPx%<1̱.ĦA.uy)zgWӘwilu0Þ=f>Jf)4yN>w)>g4Z:O_>{ѓ'`NTh/De4]3PumKC܇<%9̩ȆPxڶ"ipC:g9n$!jXIaB7#1j( (Hws#[!_M >G6}kOV:ہO{ %z.L74LWOs{ӫӍy^Rkou+e,߽9}~:=iu9oW!RLPd#)L{ͤ!WmA+Aی5U`b36SHǐa37'sDV-gsЅIVQul6SnpY3&s\T!|:&Cn7%b:mU4]r`xFBtob@0RbP4gyQ;ߦ08LqXw+f!W ph  mճg/ڤZ?r^.nղ \_?*mm,|w,˲\ʦUayGz84;~zs}}>cZoAwRP94ˢs&$P9kN>#]IU Ol$i峵`{xUKc 1 pRgK.fi ?sԢn>b׸5مfIxIk& 0N10{;lj!Z$^[f)B<ӛ')jֲ.~UƺK>L!'a5rn/1?*ֶ֥3/RWk9j>лWjt)slj6Aon{_ԄN؝Lz`w Fl{ =fA!1v(q(@#'k~ gH"lQ~  8!>my$XSQjsXܱaf~1׉0mż4,Lڅ0?۶Z\z)[)ukv4֕K^e-å<,Q5an#&r֢yp9%}w4kR1b2р;fSwX0ZM I2vh5}gsVvn0cY@\b|BHXQ5{vb@VM~h(IwnAFt0E S9;Ą:R] I)mݶQ/q > 61ִ˰W"hH©ԓl(:PL9Hb}1kCVc&.2&-2xg`,zz]$8Nؾvh4#6Ph 'A7VR hlDOcݭ3" A҃It@Uk3`d]˺ *U3p=*@Ոvu\A Kk#qL(2n"8wC!g菙b ak[G830A@I;g}Lar MA؁cn!EׄF0SEG20}D9 >ap[/s Jߐr4cGD#4ҧrG@uxtNk8yJW*ZjBEW!F?FNyM"!񋇦.~pDڊ!j4CKj))n 8^93 l}Ѐ|ϑ9c:؀c.Q #BTO"wX#k}9hjZpF)&Ro4*4î0k)6J!☓U3cߢeڻPMJ2[8POaf1MxJ8z5-8Yd7)_Gɱޣ.0T89(<Fۈ3 [iHվBho4Һ~ B#7mh"p,bH3єw[tobg, \y)d+Gc)&ޯ[j 7Őjv *=6`fTm摀lm~00kv:5ޠ,7̄ a[lw3:xӻ\N ;l}ǟ$͟Hhp C rWd˶<~]/9dc&6vA}MToS`5 L5oֈM#`Cغ&|Iڨ[ByK1eCkb̓N =jo 53M5B ˆiФgwf9 䅤;jh?&D|Dc!p;uڙ6 tۺ/c݋.$Õ$E 渶5.Y?2/>z͵^ ?nlZkڨ uٶˋ/ң;#~p!2x:^cBӫr⩍M]``.Iڡ@Kh'\1U[RҘ#VV ,,a`:sDk!.h)%J6t: ϣH)KkM4t%s74& }ojөNDQkvC8b.aDߏlAЎMRp*t'|r[Fb9$(ܠ KDdh FP?<%bYRO;b?~C/ -T G<<խ H9ڿrrHr4 %r %l)w[I5B)saMG|Ҧ] l50$}hf{e $caDq*uB 0_?:]t<]',ғ vI&0L΁rw:DIf š(YeIJ3D:2kn k9BGlt k`:iۢf_W6 3uNd+e9iDCQ4R12@IIkRG.ǦF+awg!~˾`{AVC|B{ @mLT(T@r24Wa$a_#eݪ{8Q^_Eׯ/l(tSjm6.tm;BnYx W!$Z[]Ҷa=oSzx%z 2 6 2ZhO!\=9|y'!m>9ݠʨh&cSt!7A9b$ƙH r~m˚vdFxBez^/^6ҳXXZˌ^,tL'R&5SH0XpG'_.o^ yl&bXm=ŐG iRQ^୍j3FbM^>5#&9 ?IVS1E4'|siȐ$.A-4  URˆ_&s,[/anzR8(},8=Ep\X>a(As C T[I>cuֻRև\^l"3<I;R֋}ZcMJam-VV'&10VVz!knA,}& YrFf\ c81Y!'h&m1I>6,pSj!7[05BbY(#"qpl y=jbfڸgWyl%dHԠ@m'\ں.n՝sh 9 n8֌1Slu[o^ϧA|ٛR#AĎT&aۻtxճSiZ'SR TAdɰbm4I4R(,POi[!|xT)sCi!©gs'M ̽jiJwy)CMj72YKIwA.Kf,_pӯYgϚFr2Iڄæ=va=Oi#9r1g@R &^4fou40r3+Xxm_dW5&3| pPUM>4 qC0ڨZ'd 87h3VɁPCc^y2L|ʆSIff^(i+Rm#;!{$9&!`!_"T+ s)dwǏضj.bb ͨ@Jbˁ.;цO^fm&/pEVip;{Wcpe!L##4SmCfKPkx찘h10A /pA茡`f[Z@p20Đvjc+CLrwg3B0;dlϘdZakĶl5fFz1$3ՔfśH1|v %hFi``+4 Z)-3SUS7dP_EԱ Vk ݥzf[аH*BhVѰ))#u c昩ƉVr#i:C= Y$PkZewM+I>|;|GNF 5k'8KѴ2 d4hwTTP TXj]-;Elz ڧLgT aa3 ^G|abmw 5䁅a)]X˃sY.۪U)<mxcBaI) Y fGFDuk|:p9Ln?*} t4jj;]eM P@BvV:[܍l+R$ߘeݕc>eڛ$HpW3Z*jfSd(v!:i1d4!Q&@/^ 0UdqJ\ԍG45[ZZYʦ'՘af.ޝ*{djaFl$X]Fljf,aDǮ;~ceE< {nTjyA P2%3PEw(RYb(hSw1.ЇYFxӃ{̇@}>WϟgWoB8!H6a^ zd|= uv-Wb3\lBuIq(x%^<&c^( " ⲬiU K5@Gɘ~Lv84l 4W 'Nź6@@A3N񭞉aEC5m`pf/]C5Mp 洧GĽ 0GVΟr k"0F>MoZYb6в mb*$V7Z6验h!S dG0]ty~YLIվ4mvWh;YE ZBAܜ} з /2JY1O<$ c=ub G a_zR ;#=Zo7'ܝv k_J#s'ajNև ,y̽bx{C`\cܶɞıVFɆkDamH_\* ڥ=IJ-AKlZmm4(WP.h0)heL`4.(|{HRM~\vmtV7 G}XZ ?0h^Źx5Fd;~|R5-| amҮ-pjt#4(14.+^L&>C١EC2ȁndRNј t+F8bj SIqhkI0 B_a8(mxKۤ~Сh`Ѷ-EIi`7j XbP{t) ! В3rhVAH!BɌBD(-6/b x[T+@a4KY]h}|P~ҏ6w0Z=2|;^{xƯl\r/'.J:5 &Y=gP;| ]lVCEIDAT1j}7xN@Uv8 RGA&|Pv;g ELsNѦEZL\,{f&1Rzяls7~_a{^:TueoV!!*DvڑQZ1Q1R ^iU"RlO><ǯg$[|eYrKWZiȫF{/ YbѠ90[:g< qfgLn\@|Fe ̆`k>(g]"+1=!Rvl 2,W*÷@Q!w4g 2=;[|ͣuھ:m=@pxonɾQ;yryrboH\aeҐ)|8K%ܓJJ*f\tm(S]P]W~;joz lyg_e^t\nO.o7UP&ev7>Ѥެη}o@pŮA<ٵh8IZQdT[߼!JiV<{coeGVXeiw4U~}4֕]eFD~eQFq8&2Z~+;r!Fu!e؜ي 3J[gdFEXwƫ*.!hx_WRZYJ2:_:|bZ%]dS_?O_n <_ty~~uӬ듫7חnKy5)L@WF{ 1{JI9_zVm0mBDNbHؙ٤-&W!q2]tF dkJ!/%_,痒8Nm;laؐ2jb~@H˗)|Ͷhf0Vig|HBюnB$pl,E<ǐ8?d\,J(B7M+RqulJRc65rz%Kb(K:?,p4~?ޝg[bJB/_9]_^^zm5 6-A/#&")^q&W(c/t:{㝹q:1UI*ԅ_<wnή es#Y!GI}MD)RL)G(0 1Z]62\CY2ul XI Uɬm7/q o֔$Q- /]C;SL_XQ%4O-Y=\&ctvٵͱrNV;wO?;yAP<]nxkoݟ~/YcrՆs$$(f꺠kkQ3uss!k !nAaVd:[ΦmKղJi\Y7MwgcS )t 9%H#Rv#k+ckjo2Ybדe ʛ}b*рֺl7MuW)= J'J@K5S*iZ`UޖM,d9; d!6$\,1" "y6f={rb+Xn /ŢCUZ)(Gn}WH'o"AnTC.0.gA~G4kwQP 8j4Jq_=[m{J3EĤ~C=xNӽu絳:*6Rۘ1_\^_t6s{r 8ou]S)1bB{ƺz|m3;V)C_A, Z /)W|7Lg#$30(PRX΅) JBR8'U~XH|mV FMYh@WmH\;*,_~{חh }nזzLID+VyW|o鋛UuC˔-?v 1(q#ӌfٻ;fb%) Q3?vwpxtph\Ox|ӍxY<*0o ̺Y_^fvoq{y`GvS[P2gJUJ=Iv;Yr(8(},\.yF|M3ۙ4U1@NNT\)73_fN`K1 DD1 K!HXA$YYm3 U,h3lΞ>ޣ~>%r#W[V%% 5t4>?_il<&;0щWV0! J_y9*Q;4>5f=y_<\d~/j8ҡumFqB+ד H'vi_Yk~x:Ő1p:u2^ g$7F ̴Spqś;>5l6u]$)mԐ׫@7;;Ie=aT sz'x9kw|6׫O\j 2f0W9#s37!>d@ "\CFiDa?y% ,0!fT«8K1ONοbtyWLw~(8)[L)ZW I31IqV&t5R}21VJa\#6u 7zHQʉ}F 밪֕.*)C;Ƴ1SȩGB N.Fըn39P) ] ^Hr lw\\6m{t>"12d?>JJ-DouweK&dǨ" C8s b ^UR]ep [1#<##11h"<[^wnLyL `Ir)8̚Q=w<ݱzk/_"ǧ iKj_P1lu(vW,Ԟ_d~\&FRsƣMf2Pc11QABrBPjt E]&""e$Fȃ$DZ?jw\萰^~Ψ?2lIZMJJtO>M+mFK; `,x}ff1]Y[^ӌbī . iv9sgpYYg9[?b%ΉA(~?|ow\M6Tl77 8tY]cؚ.l7O/Η6=[5l309Rc$0qO&m eOTOȌjxU,mj9W7ϯ™7ScQ*,7w ȼEx4wKf#f_5AMe)o0`Hr=gYtL둵! YTUtڞޙ5j#{UY3fo6 KVHjMBv|Dq%ccH!j`8YeДP8}0ʒdxmن4o DE^C(պ*w޹0p ֝bL)HyS0dH0JllV[_٪Y ۞y>AjT"*b{&\IS}mAJ~ㅚKJɈZKrRcNRkR-Ӣ6wߓFuR0?f,(!TJY 9 3a;y}DZٮ=41Zw[H KFŽ 8GS]7Qw*ܘ0Je0݆R (z?!,bt" e Uc%UHx)[cjN7MH6D|THL[$bH!g=˯~կ|3IHavg?b3՗}__ ~eesquRg>fnww{E*Ri) [UVA\^n.Lze 8(¤܃5l.ܤ.Z #C g}>FemWf7c_M5#Ɏb)JPeIQi='($dg QހZZ Ȉ[5Ne93gmy~E(%M#שׂKyW1 `S4W$~H )i;d4{3~sOmi)%@pP&E OVm.xu8}{k| fMyztҼyJHD#Ji1HTIzoܜ)wVmlJYzX9CR1JXKtQb%)r"Yz@:}xswwjl˛'go~ߵKYFtF30RڅR Qi*]]Ǔ/3DuXV=PL!E+l?Jѳ//>E֛ݝ}ßz'y L/hHYʊ!3|*Vq$5T(҃,LE[gI^ҹ˂~uf%9cbjo;BO*Oe fNXg"=*FA'qSoVr|DP,Tlq*tl_?Z|Mqzպzi (+2ҲW* 0qy2Y;CT vmF^ڰTmbvY3g"7>ǜ-:c161vo|[gP⦃lV aQ?b E1!8M Pm}6.vAJ"$IUM*v(yp@i4)\8Ӂ@4/ ;U+kDlQT%2"J,MnIg@ClT&eeu̧ feRbnTwE@h\ jchT;ҋ/Ԙ-[Jh -$fֆn*" "~5:޴ۛ;;㽺9`Ē49#&,ZX:ge@ S_9}/>r*TRl(^![pT/|3qtR;yq0 =?RݖJ)(Sav(T63wJVFҖ^=rI+{) (vz&)Ӌ6Ŗ*,xG."u]ʻEe v'ldYE7xqd [Rk]ΡԥxNi쮤17tSBwOtzYZ:e%BU1%NdvVBxsӾ9=bo53j*a|Ҁ6QhH)I(1.?$`'5PR("~VdKFr[dFd2Uz*B(-:?)Ui* 􇱗gߓ2P D ET$ T`C ہ̡Vd$e,)j&*IH{^W9A,TNGh4$"e_qڜD鳋-$ƕyDjvk?w֮z"C]E%](=1 偓Vb;$.t; єZd`G&Q@yCPbyЅJ^8`PxSzh9kyE#$Ŕm%\[|]LO JXQW5'Hb^q/)Mʩ/̪h6(QT ɣzYzlG9!pmMLw{_=T ahUpn@b[c#dE]$":&*E2f{3}mvCA0#619K3 m+9 -.]_LSEXW:b xWBDVsy 1|:Z8932yhA١y6.7qզW:z7p8?LUa+|ӭվ"u$1ʊ[K`NYūed5J΋l?~Ggғ/^=u #%"DmbjkujLP(QA3~,f ʷʚ2E 9߮tC?딁ʍEh/(SJTJ %硱ˁ< KHAC @P*lFҌEc:eĂU_y mN='J=Rʣzb4.zڏ4mu)R DL$L7n\;dj{̓PҊ:Oak7_^$_l3LQ]RNx 9J2mgno7wsn8DuEL5|,GB )5аeY B6r\M+_'9?+] *_q"tR2Qyږ"V,XԽRIĨr 0As-w[0Ϸ6tvm *xpQSgu@^[RB!#X,voRDҸQUZh;t6} V4n===>.]&^w9Sc`8X,;q]SvKQH@0(OՊY4:DZD6d'* ֔;fRZYk@lF;m|ݨ᷻#a,9b7"#*'g$g A 8vA-/Y9Qrmoᦏ(+0QN8g5'7rz}l<ӝt:M[g ;e5#k*JFk[(A@,Sa"&d)9%c|lmMS39(ء(Nx9nM 3ou5oJN=%u[#a<hRW⠙TCL^oCWc7ۀQzZH777JޮLCAԿ9G S"B t~ՙ-傹|,w6^a{/_߼xvE6wݪʆPu@9ߛL;E)EQ(R({7ҭE9ydc"H76n.f;"w0XO(-*u9 B=2?d`Lb0^9(Ϊn% "҂|o^*XjDS$x'\[¶ WSA3٤L917Ehfvrk$ᴚZmenҧk\ '6(oKu$z]VOW/_\=04HLErF,sydx]նfAeRV]є.-Ҫ,/I>(%siYel3vk=ulF2Y$<GlEp8ʁy8 r4T-r@Y &Ts\_hHn+pr[Ae,ͮ^VwvB)J]QtŸYꅶ1 )&!}L}bVGP0cޟ!(D$Lh`᤬RC "MFNFE8vAU)9|XDJ:\gÕZ{]$ʄp$"H\О.iRj(`@l~؝} ۳>~l_{Gn,%u0(d20[ΉTΨxHSYOL(1p0KZqFAMaIѳi*!}MZA2K_嶩o0ʵ1 ai{՝5Q9ƒcf|W<&!E(k**7f'!b_ZWi+TEBSRv]!ΒFWoX`z*voHCe#RodSwoƪڱfRa@J0h ,rD_AT FR- )b YP;hg]BLrf?Ww./YI8k6mB64R9rJ='&9X\`*HٵtaB*})%kt+t㭆F}f晲b2Z\2K*ɴ=CO?_oS+pi#/&18.0^dad E>;gTU-WԣMРhS 7\Pƍ%_Q$FNݘD—(iD,J}]x׃.SԠBaNURͽ;eMqgՖ@y6HGnŗ'Laq8PFF,gRP) 31؍2Cp]I93ץX'Rc=Px[NEUbv`X7;Ah|2LC›jխ"9٭eҝB*/8Z]5xwۥХ(ehr#Ι(Wx|zAW_uu=G+WE{ ]Lƍf*Oˑ:  FU L¾_Sע:t*H5^|j;at ټGzp{.j]/s) OI"{~U`B 4J AA6&$PbiF'cF7Qx]ا'Sf"t=TMb^]/7}۴=ۖH!2 1 ̓THR f(}HUx$&[cH6S]oPs")#'C¦US5*m.ۋ ɬ uƎqzyֵvr 8]&<2>*?t^!_P,߇KQSWy꧇?09.ỠVc?צ\NU ]*KوM=DS*bTK) BJ[rP+mG9a)0%1a1vWI5],SRkȻ&^o/ח=vo>[ĈI}l;Ιmꕶi6G[aխ?E{,Dq(Kkr|f֮xg a "s a\ƴ2ޣ5}N)ac,QtOv^HܧK&#J-v%R*$JҐ Y#=:jQ")= iyHqpyW=]+~A0VUqGl֐W>B619=}(?xoշP'}CT؅*c]Fwh(­rV)RprS??j_?u=/IiR؆k٢v'iku|1C1%P ғ8TbDԥ6jujD@19&MgSC0E<׋1*mG =u _v#Q!ӿՏ*7H$J!Zss#hU6m\rHd&DNENkZ[d.C *X =@j'g;^*vA2&}[wn=LZS#4`.(r R"uqy~IZYyxS9oժ@ ^)r;SFYO^.PF>jm+WMLtĜIB"M*q/T(ۛmv;"ii1U[jP5*%'v>we!"Pya>zM9.3uY7PUK5X0SH1"C)R9FIDKZl޹8UrRiV|Hn _"5: s/J0E9^+X}ޭC˳zWpCfs:w+#8rx-?޹;=O/^efğU",q5.'oMq2 iKjS~ZMS :IT)F֣cQIpjX=־u Ͽ NNy}w7OOΞƶ@Y#ܾ 2xxc0Dx UF5n?*=1Q^C(sa䜕^NvTrp (M -˞RZz{VtW'E *DPU ˀwΦ/mx I~s]퉤z_<}r>i@L-[]Af'g!f(y+JL]Dx7_}l14uNs)r %[N_zQr zR(c i0ۺn*[/Я{ѷ`5ۏE9;E9B3 L{ !ϢJI1 2%+uBuSQ[Di&:;@0sNr߲(@̉%ԦRۥ6:uxq-;DGlWkWʛjW@injt7wPķ&jƗ'ؾ:rt/rֻ4MeeK,%~ F1_'a( S7[cvQs =]ؤLQ[gGAWo3]>Akx:֘/AЭy)xk%|OοuT9%}e8baqU 9+AK.9@I0VQF3`Р12p:+hpxT"f1CwO=.}IkvuMR vׯϞ-:gxP*Y?{ym}^~ub(]DEcThUL__o稾=:k8;:TN10;30(Jf  LV>2rl4'i0Lтn!H yK)G.Y@!q {께zγ9+ 7Aw2b: k׹}yM9wAV߹z^۲,~}'ѯ}57=w~&º*oo~݋'=!tGW0VϦpթZ#w»qN'W.3i˴U|k)(Km5R5U."GۏKLTf)25̔YHm ˛w//aJK)(65"G4&n/|%K>ypJ6²*ELJh>ri-QhW'd^ Hkq q(&$R `u=-ttZU`Z:9FK$ӋT.~+ MDy S-7{.˗7;E Xv&B TF_/R8ӱ·!Xd\M1ힻ4)&D2s(R!5X~>G lfRۗU-ٴTsT hRVvg틛Kߢk/'kz&=ų.f?5z,#J_??ߙr  j-]^̷!*ג]Qݺ5\H:ZIga hxYe): 7a(}XRU$Q Iq0;jtiGRˋ$B+hi)턂R |ޗoL|:2KkQ ɧ&ޘt H\[ j3c*i(&xMG.F#W]k ۱ޱ;q;l`3(m4 7t) R裗t5:]я^c:n%?)wi.~*Q{ߟ~g_VCӶv%ҩO5Ru3c56gzoP05"JG7;rsDP=9NoÁj9M}ڈc]-Ώ|w㿘xJ#[O)lɍ~֯rnayBtOS0Τ TKetWw<7W;+_{?wE\*u\1=iFeZxҭN$ւ­WG-zU Q^Ly l*6Xy2feАXR~?m;{OW?Nۙ ګ ѻ߾w0xsw>tQ2w~cw?>a;~nuPw)O^^v>%3 7~HZ(ȩ.y7R gx̶o! #(]Vй'PƝPs>B,YImJs-O.@n&Q -`<W[Fp\.b|egR]"fmm[ZI$@E">i W–x0Gż,\ZU}t*['^?:yo?RU#fnÒIJȳ'q]毆\J)TsY&.3rӡʼnOfh{sFNՃɓ` Yn&n>?v|]XP-6C[}ꂹ |Ja̤\G !: Ueބ!FR=}??=/'oDpݲ)[pU:_rn\p"<ҜձWGcWLE)sM^tR"aC-=һOWߧo-䯼g %ۏ\DOX%Jkﶪ*!N{ZrK)ǒgz𿰑N!oFA'})d>^{+|(I_:k4 fi3Scl$(e:X}9zDs 2@tj9y8Nt|E?0S7 tH-A E[ܹk?x sH`FTTFn "YSP:U.1$oVt\!r<+"6-|ShhiM$nVon`l,SO#>B} s=llSB+&l:uJqpI)e4i2Z*%T_Rz{?y P뉓*^vο}1*0*~ 8-;e[BK=])RFj@Cw8k(mA +ϻU`Ls5NcEuO(cr^8 e9odJ(4Zw!\^xQnP΀(8aC}q1~dC/n<2j!Y%bNvvMwFރ*$sMYƴ":4T伕O[ٶ߷[S(עZ9踸c6.1s8|]6L: vzǎ3σY0FۡR߾P`XN V 'h`5q,D2_oUz]j(3`S(iGŰ??<;?zD谣:b+ʨ[J3aǮS%d y9IFp3! h3v8%k!.;58D ZՍ5vDϏ/KLKٳ;c)ԏytK{Q>n^}zFeSo%V>.%(X'>ZAlhZb.W-oZ 6 Boz݃k&V O5ƭ|/n5?I5^_olVX1!e)s>-|/G}z S#3;]m'JD2VCoH1v_^m\՘d cj:8hA0RIaȨ\?\}~^l;geGٵ/#}?AVc~n|zX8oyuo ESӥC &[.y3Z7l#Phd!ʛ(S풐X!eԔ^+1Uox8x<ՋgO$6FiF~4DZ&عӳ%>*HJQ:SzLݖhɧN!jZgr6#2/<3mڨII #BC\Fތn?oǛ!,hV[L Tzu5Wi au%0Q& %߇Ֆ.Dx8i*]]gkXPzbvYi#}+SAEDoh4EԴewû[95 'ye[`+?K_ȥLq郫8<$(Lu[Ȝ Lzc1eֺpn_ [ @Ψ Аjܙ[9űqWo=C{Dot@ RÞ>|k̕kU)H^ʫ =X^&mzA~P/Q 1JsŽL`D%5fd7^c8gW[Wq7ASвڲ= |!mtRo|>{g%~yw͓'[W6R,8!%ABWBDu8sR>3U1K<9~dOoxyw;eSײl`.'sRqcFGu3-nu৔69O?{?fow/ջߘf,ϓEt>E3E  Y,]hU] w7یw܍br@I.Үol" BN@o43z;!|電?_2e^.$s YSP}WQF揫*W軳w+Hc>kKu!0Eb}a% 3Y.gv0 1iHCBE! H!yica| _|?3ͣ'+߬$Ց z$';'1>EXp{%19Qէv,:D5"U%^+qhKݲ] [W iOEږ\}L${g=>:^5.!&Hen 'bZw|wKu5ufҕ $ e+h5~q;vW&hhԺG5?:i&]`4}7p 4L{U59-T}AYq"TهnJZm5mqZyaHP pKbkthYej.36q\7~Un|{_fLmQ04yXM>L ;_ ⪂~AjXt~#?LGul&%mS߫>lgpZU?BttDӻv[irtud]vk"WN]2nb0Ҁ VFb "l9?S}203wRYNpogS9PI 4.Cɹ֜16l6qEmURYe-%*A8l=YܚE99Ҩbr5Rn7dj)>SOi Ή 6n-&3$"zSuRݽCQc-Դ@6HW>=0dK8w?P 7y~-?/LD#&HaCi_,0FT:LЫlӛCW6jv5ɖTTlhWקeOSHo䤽q1.Ϯw0"z3[4pǔ1alǁÈ&%RyHĥ1A\HcE zH<Q02I {HUY|, ,NT60SBT0_Sr o'¡Ruj :~>K(C)0a%:wg{~ bs\nv\hF]RzVZ״Z`*j\bQ aflI8>?"ߏ$\^Lwu|//Sx ߖrǫߦ.6&D`iҐM*\9'c>+f-~LYYyu[w@z P NR 03[f:*4?#ztr1$ 7OuۯĶwNAVc^Ła>Gq pAZ____>ڟ ќ*s) :^mY%?(xWIwa6큸!q+ʏ_ސRs$\cyi7xLMJNTױ-Zz1੖T gRBGWߚҮ~ڵg;Ϝ|%}9a3is\& NlmGX#{EKHV0#A L Rov0}UY}wc]SC9&{6賏8.ch-j=8Ǎ W&<88۞9XYô4/BK^wj̇ x%zT$RR4MDLl8 ibTSuXw%`Unc%REeA_ne(p,V~=zjKfG1ֳ6!޶*N+<[ *栋Z06xfN}vqN?U3u5Y%cf:8P ]E2J|w@&\:qi:Ns^JeK4>(-5CX}*0e.ыC5 "KewbsYgT TdZ11VƶYƉkz(l^C֊SoMwc42Rlhd 8F8Q\~i.̰`5`n] b8 ތU/@: -ܶߤ13(ޯx\߿X́)]Uu}/AL)ϸ!u';qI[>r)-t3!nRR.Ny>Ӳ%Ynm5a_7-/"8% ahw-n,!7-[}6 6+-XlbTfW%k؃ Z}ꣶ 3 3,aʔF}t{Z@W+G~ m A>$ӱkf@ */(q &Q**IB[Jt?Oqkr*yɹi^niiʔ!nK !vM&)wt?w <9)OKjY3/1mdzJqHޗG#Yn l\AШo0K>$4d=dPZ?iJt% z8A[۪Qo^d}ŲI}|3ڿQs+Zz ,{"JR;cj F' pޏD-<:ӰٌJrw;̧<ՖEʼtZRr5#kSba1*veXN|<-K"JJ4 QVr&nٔ`e~okRZXf[(mȘ7L4OfF lrV*Vr`2mX}vne"^mx%Ka~@ (ZIUpwwv&٦c*i?fa-TZ\ĭx:\"&/'WB29 ~hm%c /[_8aJ6RD&`~=ݮK-MY9vn i+nw/t8N 2"M؈Vedr. ۫i,ZթPKqB X/xQ P]Ur8"H^*"yFXΨ1RKǵ'Նe@]T^՝$kl U5t̃R0Rk`Hq COVht>(#Ed1 ~V]{U_~>W$lBV$hU`j=&&h*c:xYKFMP y PpsmzxPiW2e(;")Ehw-X+SmZ1h3BK0DH}w .NZxtm~ly FdnN8C$I.j^GQldo=?uec1IPm}i~kG*YhVelVs/L}$*!畩Nҩ̙zZB]u}+´&U;/Oi2G_G6iR(+ 0n /KK41 V? kZ/VU9ޡC' l4k14 xڱHw€!;u5X/U MO}aE ݷH@xޔWfcw=ڶo[<f|R\h 픰n;lKc E3С8sY+/=~kmv0ղE7:iJzBy[3z Ѷ8TPOn/댆N9kx'U|Zٳ!FѢl!Bjߛ,OСV'T)oU1sp \ɭN51B4 TvDkPkC?y! / )|{I="'ZZ5E>;ĒUVULb]Vv,ыaD] 2 XQ$6;).pP·R(y7yaſyxuTr*tO/No lJ}ߡmPA!=CΪ9Wiغ~b:ThZhP&bzC *Q :hn%!Ɣpn2!G3܂:e RJABU>cqf:OyzCcn2.= 12 6QA`ljXK!p(!O޺N]UoTgkw1\cWRjERd7pi0WҜ.^/Y50Y7Ű_;^uoLZj=>/O$[Atbx8a-nϭekFkg ?LZv H!d[< ɴAх'HDn ȜD s0 rj @veg i H(m?rRȯV.j;4^=06]!2BV > A99y^4{Qh'LñNoHzv}~":)WI]_HڊdB _\Npw4`A9"C0Iԡ텈LM8Dz&c.3: %[A`@BrCjm+D\4|٭8B| >q0R#`28ϞD6k. > ,u ԵOG?Rcf>6p^Ū[MǖEp.D]Eӂ+Vq7ʻh#TY!D #RljMA ֱoo'T1j u*4ڃ}dhPֹ`rK1gb)]h9ڢpQ {cCZopp)_g暵eyygGWZH@aL8#~PNyj?&#_@4`Y{7%gz+#ʑBq,M.nBbJbGu^K=ZaލݎHjQ4peT2ՊpZ0V $}}KIFXSԧHM=TQ{oW| p:srs˨BW1YmŴSe=/ m׾X{KiL5Kn~W|p Zc+y(si9ܕw{+bDH"Nl͓ɇ4=ZFtmaG*7b{mv,2zhOծum?@ b0T#j,ڠZ U`]-yPS^ 2 av6q#2.2a/~?+#CK:/3`Z% DtNM)Gۇu]{,WWV)C_:BeCg֢DoVM&uJ@AΠu`UHW+TG1Y3vN Z1l=]gʃ_xdkzL!zWZ?tu:i8uD(zx}Ko=io}k0@G.;߂G"wTǰB Zv1afP`Js iG7d3;uC joxE VJU=0-@.rVDKNj'適qKZy`Q1{t)6PzlQRWbIߝAj?:~U+`F P;\ +^χ)1Ue16 [ j RJ`50GG pi@ur;Ɇ=AG '1n8`oCބi'h1^vD|kl}득ӢmD3־ұ3:Y"-[*( 4PaTFvN Ipb] xJpp҇غL1h.kwQNvfEajVd^-+S8kia9͜۽mKn}hFLA%.lcð=ML`ѵJ2=lƸsq=0T6C}pEl y1? xVBgT.BТYeŁ5hT<>ÛKY:!W ޲S'`&hPdL,ERW|艃kϮQ!d5+$%N6[}춞0?&Si (ٲRB7Rӧ 3͸4Ύ&D¨ H,r6lyHRtta@! *4fO(ni>,m5,dc)*';k[ 4+cZu.׽&ŌlR;!y@:变)}}$IBU\0ā,CAO,iDc!@Mi]r!y[OMO}N֥ @[_ڛs)q9 1H_31VR A`=<'s1a7fם ]L)Aנ÷ ~: ఺djd5^˵'M_3O3a>ZI?sؓL4VV]ҸRhBnOsqcKj͝ߔhT\~ح-gP̃ D3 FA{Ŧ:~-  dO~9vp"<-s9F4bN+z勒NByX97o᭫kƤSxh*:jZ?'w̩1j 8 u3  SǍk۞'jhi&e#[iၹRDedZWRaE{#4NG#کކ`y Za(W4Bq9#/3/i{|6Z λL@:+LZZ*Rݞ E9%0(hk0YnRxry|($W%3_>ιZikBA 8Bu1a]ʣ§s 䐁ͅ:Zdm( S)s- C&\ A`" ]&S+kP{Z7IM"GlV!‰O41ѵ9Ѧ^T [ xO!2> Wip[WӽjY蕘T:V - 6Di 0J/v/$fAs-|Ԭq'z)RD0 mT ef#Px\~r*wD SH 3(u) ) "[7ppiٶǐoVgkoh~@9HqV-jL!X]D6H{;a+ spuv6(\%3o3&d)˪#) $U!EiSadpjM + t`'Z " ԒKG-=Aubt:| Oޫn0A,PkBe(28..V VH :9]$uExx/NxF~o\hnoE.aI_!-{^K)^^ϛvƉA~C~Hj%edL Hd[0IDATUA @h]QPH"خؕ"mL] ݦ,\8,wsJGe\TU;}ycŊfkK%s%!feW@nxgVtiBb+BDi+8 EzWWSaNQNŖ`U0l;sYawH{+NF]n".`k%.[ux>xrevNq &6Ɇq=F*B AM_{A*nJ<_}[":)~]-1I8sM/gB4(MU \`**#rRZ1׾BlL73/497JX Y춯Aķ Gޕ2䥔SU$*oTB$Vէ}Do.v*Y U \a,N 6FE\rZ^>:ݪo`܅Fk PƋ{.sg.V{?-T jhFrK50ppm χE:C/.J \QFTfxaxE1PtXZ-i2ﻯM|_P1ahy`h%[`onQ#!S&4*oզ"OT*}K0&OIENDB`gift-0.2.0/testdata/dst_color_func.png000066400000000000000000000650301513354670200177760ustar00rootroot00000000000000PNG  IHDRxԅOiIDATxd-Iv̼k{ $A[A `?C_-l Q-2-cD>Lw^V{53#8[mPWuöl=R<=GvH.J- r:Z" #dRѧ[<: 2%~1Cwv~Ng Ρ`pWo'7;OW>[ZwH7⏎ t:Zg_ oD}?nwqQƽ;|xN^rn9gdv#/4 YF eẀ8:Oۓ@R"Ebb5O6,H65¯ɊA^3l/7t&ĎwPz|85bs?Wޙ1k8mjzt@!Vg+4 8z㯡~}ӗt&es33/?pxIb~X'B7"Q˔Xhr’t;!j.W%t w5+!<}LprD[KaEڕiq3hy9*|4*n8@uKޡ^H=zZ+7ˬ!DJϒ߇w˃F0zX~p"_x#\|wAjٻR,|&>&_'8D>?[OY ]W~bbzV=F;3|- rB*$F?EG'f'b`v>"Em=|ID=%Σbcʪ؃uvd]@=НT']3L1.p}LNxGS%,@}ԏv=Dij>sX{Rgt9-npt@s,F/pTS%vѷ'{Vr|s>>y 78??KZ5^ \` kR.s@z},%}Sq>VqWf:˱[OWH<;f*Re۳2>Lda|C7!&$zY5 zq3Pf"O]a9!դwz:)WQ$) (MJѶ!z%csbRАFæ# -`qc|]DZ q-}\7# O'Y+ ~lu]arMcplC - CBFa1!,Rc,p} P$'. w3f:F5A\5O 1SU=}wd 6@vwB&WQYM5H^=VT?m,U$xEQj([g]J2(*hz;]$$8q͖TGoz>Z`nLVCw%ы{#L7}Al6Q dd5+NP;ڬ8vF_`TOsyM,_<@<}|Gج*¤}MaV#}twxy^}̙:A'ii*m63V5I& 6ly;oj9U]tDDenأ_[-]$UvQTmYA)2 2N7w$F?Gopvife%ީ ȱU/x|MGq9"^%0"[mW#t3j#rV~9k ]D՛ȘfXLg+#b~!E{:+ В,36iRn3 RPԾX>v+' f4#lR&Ⱕ˃jQ`HkHvAeZ>Ͽ\@uef>~6pxIOrXz/_#'+zk;N_je IosܽGjgt=XV.DN螶y-_ ^ F!1DOwӡG!X;ۚlA-;PVSvIS=XlFݜDmxŀqȞUq<z淨7͢ y TewX`$'/WgxIyzTk:F+!6wu,pxKfܲ-֏p=őm.Yc֡1iiDYZF7$}=;&u["[mDj*u&/K8Ǐ1 fBni*S |&_wK|;-c*lTd}h֤p7/iO/ *bO9Hv3{> htoQ {b'WBURlr9uջ˝GK ^x,%[8/p›ferQl'~CnjtHgl;51T>b9ꦅX2qQ/&Ozi!5GGމM;o^vƧ*^U^i&vD}K3DYSnd&3P‡=yqϧ< TN`+V5E0Y6ON3E_eJx_>^|C+9%?Y2L!?\[ ^7؊k-8 eocV|eeD݊~{gi#|[5\$X{L{ƑB{K\ú& =L؊'7{J5%=j|I϶W;-|x=`wb^nOރs]>9DnOpxO*5U!ٸmg ` *Wýg"2x 7U[dG5x~('!d3]g='y3% m9=3T^7ˋ-@3V γq LKVė<"30ZM>QFWM^P#i~:bE{Go"m I22Zn[BPOW9vL&۩R=) =$ /UU:x3:#\~+vqyAlȅ*a ̇׸L$"@JNa<.1?#4}~5{\=1͌ӋC,8*4+ Ԋ(`zv|xg\s-DӏnnQYHI c5[pMϙB-,G$^t+s@@#K=!wxo[[]W<aJ#֮gǘH3L 7^S.pBzх}THW2Qk̒0]P#6?G߃vb '\!=]װ]Hf=x:N^bՊ- h;ŰbPD?$=]2:#LǨc*3 f؄Dos@$Wtj3VPt"Hmϫ;o#y}Ę|C2FtXcVruH 0=ICA&3$b v8 YXn45S ?WEE>$a|K,< 7tpK=;ܝū qD[Lר yji 0TkA`LbmMR׸:%1FUD 5c ߑILk :fĿqɽjRxSamqSRhQ/pwKV^ o a(<3y]WZeDYD9AjGs$,YyG'__z`ucaekҩ^[^[E8Ck"hX8 pl < Ub#*ǠHHےh33Fj[pt}Fbm!g_匄n6$4*Xt13P  &!Ђ—l5@{a.-[%AEyQSV ɇ<#9嬰-x5[՘lj1>6[ |M(HzaKh _^p ioTS1r_Gwl(d|_>X 78F~nj#g$%!c6"ղ8 L@F`Xp<9Ksuk L"ĝWkZ;X>gdb*-έza"Ut2!JښZT0XćoP{0Pb2* <9,”ɡ9{J_;t;њsw>Ǐ>YRBy}(ɓR>7kq*\'{3j:T" !hhT 4lrMz`Ŋ+N5R+}] }aiFгJc. b-SBP'C`2f ,*2щXT(NJ|%swB6v̪B 5PEqdIOvŚ& aq ^arBZPT̥<#r;jQTM'yF%DvMŚ 2mr%b!>)`!0Nh-f0v,1%'sIȥ 88vxMJ{jN{ |J*TXw2qEVI;!%шAY/I7!Q ٠; Q,pX]݈T_bXXYBU,BR7aPE E`EůZao%HrWt.n[XѴxRKF5]͐_?ß~{G;'==nI&^5W>!ΑN%G_avA6=31R'=UOb_`\n>D v&}W9#BL'E׬qpxYEѺ k= =;1d**;5#/3ɞ/"Ӭ.ixIaA Y^q(QoѨ4`9%0Z"1w0B{a \/۟!PdΎS&v+Weٳ ]m1UeWps}\BJfX=/qrמcO.C'):SBIWw yb*gY 8)>{GzrMן-cdblgnPŶN '55HK^-o'Lx*obn=dI™ IizoڰToNJd+ ΈZg׃1]㶜w诗SAA]w,,>W#,g5`*S1) M~zn9G-*5sxG@BErΚtu%g`'>i78!w.F7K:j8xA_2ś++7&>YT]N 3FXRl&QZN!Wl2Y[T(vR9YR "_NxMaoakJ .TW )hG  8[ EM$dg9VU3wt:a L:NOV^@A!E:> $D%99@l!9N/Pdz“jNz,f2X,IӋM5BWoN9Jώ+^h4,a`;dkItzi[M'zN@p''NXǬG7l|эLHʖ I"k0IĦtzlKct'\j㗔#{ "Z^҃$zBFUKKɷ7PݰA! HW+eK?YЊlEV%]&걊NPzީlҋ澂u% B|Y 9YFttM>J:XuΚ+o3:p }=8YTQQpf9F_ZN ExT'4 W2Ifne&r!v"!VarGynǺJ'쬇>̡;9/"dnCK|<+@n.I.VQH,7k,K e'_ItU2 e كMLJe˟T7ATkJ_|.g\fTN6;0~I\{[q>^Od:<`⮒Ƥ_GU8Ê׭ Ts:78y~X8,'@:,H;tYrxq9X73K8v?[FL@$j$ b'0g->Ȗ^[}GLdQ_ v.`R|UD1A ͘jL4Fw=bծ(dY=י'%[%G73+,cuZ* &A$OTxHuTϨ9>;vl'kuyJjh>5KUͧd3m1ɪpfScnLwٔz P(?2 X||vKJIxMJN Fay *E[mI}nPmɳa+/AL@bꍯp'Y/]I1}.޽Dr$-TsK_3y\=vMzrJdT^!΂ۉ¤~=[Ҵ7l,$$(`#E4P0c>cd7*=d{M|Mu[8H$d ˍg)W1C`bՒXe Cqc`L]`B8i<9V`۾³3:`|gr`GVc{WOxOG8[{-q 5d.4)S@I Yfgq25 )95r"5:`x 95A7svjK2,V2b$@ +j u,!~WRF[,E^0a?d  az!Fb[_`MQmvp=ª=32"%pQn9GWöՉlEs$)zt"ۼ6CT lUC ) (^ofJ;Tߤ%7fJ5քQK0>dF 4/ha d tn'Q>BFuz+QO0b [{=Da_c=O|e-tg$P*V?HڒU3;#=f[+s& au*{l9j \KqU@U?b!=֌ x^w. YtVqzEEkSKN g3I>!0U̔Cl9)1Y/Iz9Ie~!D\Au}{;'4gk !gwIH=N|3vIui.>p o x/U:(LfUO ><67&v>N.2.p}@AkgtQǨ#k 4.E;E7rwIVy>٭mC/ ]{7ܮcsvb,5<=15Ǹ`˃J y͠Tb$ZUJ!`O)HfG ,f 'u|+EDE I'LR{C[/_SI4ZPSZgbm+BVJRzW~b'q\nKܲLԤet3`&#lٞꀣ0Kq:^DYsg3<[8a s&=\` s5-x͝ p!垜`5t)RR~@E;|H Gz[ al9:.ꕄD0"91 Л2,ChYJubO͑Uv̛y+[p(um40ڒn& 8R_oqu"D:Eug7iug}A56_pap\(N WH746P/*yU7_ijB,e)P>X՜­=C!F͛*3iS12LAIYŊVgJdV' <}zsʁך݈ u-pph:4YDZyFMr+ H9=M5[[v.G  \c=RPQwZ$?*jײGιġGĿ|+НuF-ptjցl4 Yxr% >҅ݫxoMYh-HG5!UD^Lw،"0Ώ0Ya9aRT|9 !~prWr BIs M%]>|tL5VLz@)rXqrJ*U¢֠]yEkiI;facRBP!XɬܭGkV?lbhBK]e68JȭvoPYN5ᮤ@s2f nIM6j .fREeEI$9'{pOJ$y8<ǟz ~$ۆo.knZ+q" S2c52mƨ[nZB*tI\2\!6gwtw^o}9}^rpt_CӲudYt_MJeWq?|T0MEV6UE!+>7?p)sv&[ [HvLqNπS1pYRV{75(v>=pz{o>8\coxz;?lX./-~ ~|+5#+zbϜMn:Qk^B-N.p*gv֗,럪kGc0~ Nwэ[<|)s-7OjG*Vl^I]-@mqZ5&`̣Lh!S=aD{ga>f痳O[x1\Ԯuq kۿ?~nx3!nyC6C i[YSȖ ^./}@>UbL ߟ%ۍ%'ie~gEHm}p6IMT_0kqČ{d^+lX[TjVo7DLb0jDBSFz Va!*iW&_(ĭ8:"˖L k%/\hB0c!ޏ(bdzJ\P, |HS~ sJH 7b!Y! )yD~SZtkLnPqҵ-bys4JdkMdJNV<}0݄'ݢCQ_Ghϲ'6z !=7ov\ŤC2g5'U*bJGm=C9K ZGEk<-رc,dI_ӎ _ɞ9=ԽC9~<z6sP,?.nagw>[K[I[#20h*5]w:J%r73B ñQ ܻIYIeH`FAl[OM/E<~`>=H1mC{OK4R]g`/{gq[FG5+Z@a>rjWbNК;J t8Ϫ̉>r N39d5,’U Ug5 @=9+n.ćKK$ z r%Gb73i_|i%^y?\ Eᝮp0+D̎.pO9}w^`s语=ydO +6 D!{^\I-K݆dFDk#)3"n~Ib9HXVwi'i<4v_Bef $!PT'}3+1 %-kl]aA$5{ k=?辍{cD0y?&ᅰ8zσ\E|x!n'' cu0o H*@U(%Б|~w_t t;Fa&7HSluמ.[e;szWq9Gz*v1y!}pg'u$]=f1)`N_sR'"%%*^rqej}⹟Lۀ~FQsEa6듧 yIp-~X~WPmѿoL~O2)˒s_C:)-wY m,+8[ea96G<ى U#VZtH%oU<d)-G sƚnVOsu:LӖ`X A~6B#9jVX8;Mĵiunanb |Cl~Ƴ.p?tːP|I+;_,]iVJATi-𹘖K wkO.Z Yu[&tk>5]dq~6][ҊW#h.1$[u"A{NmQ~ I-I a4Ogᐾ^jIW"Z͖mBqk}ˆ1ZQ%eg[7bjLh:WCl魝LG5Gchdm+,}pG3|Ä`,+ 4sTK n>NE#9rC^Iצga-c%3 K ,h}GWP 'mm(+ld)+K<h5=EihPL4z-np9}QdQ@$Go,s)Mi7Uf: /C&$%zF44m*g,Z{ :-lAWwXDXk|;}rا/^d_o\WU=m'-e#%&?e$Du7\] v*Sֆs4P0KkډyvX/]4r:̰v[K]Q{$3Og=NIhEoY(2 N}p'c6|wZO6pwa89x{S,ȷW<+s68_ǛbU& ,B*.!GgTU=q!.4EgȀHӷ~H~h~j5p[u;O37=&j\R- K݅RVT5?#ʴQdRkvWVʎzK#3:B%eyw7XtIF~0;4Vj_G\0 x嘐lw/k`_x{LrCv&l6;rޘ;lNfrVTY9iC2L5TwXs:=:81]BИqzEj#X 8ґCQfbH6f1W$[oMg mEzS6sٲL9)(Gkw+k7SC{K>SO{NNM e5:*?Kqmv Աm$p5r#I)\q$[_R\X`nwۼ <(f-'!@*pzgSL>~hP#[>iRt|h0-ZPw5$116d\{+/mjS,V]O֑ӣ;jǸ8C$*)i}xULFd4:Nh68\wS2MN-#}f:gJF.@Kt9EwB$iO_=Om,3.}4Sss?#!=53~\?mۙwHCb2dXV*g2_J?jʡM;-NcXz)J R+wCdc=yh5c!vg* & \*G,М bu,8s`4)R՝KXau/TQ0t/ך `,sjN\m)|+IKۿiAǥ,4'8| 7h"P2qvE귱,zO Ə?XbQ(>A<+.$ ˜Q4XS`JT18'm213>; s}C屙!Ȱ0( !!vA˞lyBʦ HȔ@Ơ1K .QO;HDRՔsvXɺo-Ge { ItSH~qV#rڭgohQN|,!saL*0]M,/"ex=Q:hɛ)21Θl+ƾ4 y"SwnqcÞc̓6#LLQbЯwgY)$Kd3 wG,qB@7kZ`S5i1qT(fl:Mfb3vnE"Z42"?gޕ=Vy&Ki#)#w`Z^A]HdF J΄CٲY)u;]JRSR *1HwqJK.(L#bĜ O =rUgL}_ٰ([r=>u0Ɋ"(HF4w%9@Nrx{ VK]ÿ6c"f z;nbxd#8 B- l$C%oDNd yV<]GqX+&B5 maSq]nB))! 3^TdҩhGo1H[ZaέVLX=h}m L۝1ؠv7ٴ6$9K;F>7Ui &oʗN\8fэv:~}\ nyVErrMe[nZϯ55DvQx3UWDW^ʹS_tϊƖN9B̃ ~zPk$/w{5mr<|Ԝ?!d%k=Clqe-`E5 j]t%vH*.i+"d,8ƚ ؟ E`Zk"~EB[at٬~m6t4~I%1@OT6HR[7CM ޔ~9n\ۦAiU-o!bč oBz{7̖Rb83t<_Z9=gO;:gigdaѵp%R-X &indva`w_= FXgQvQXn<83)72ә cET#x DeK*}f-{2)j*9Wc~ >Sdt+=Znp:gGixV (>w1QInr$pzbA% YliId9BiXlE2Kկ4qaϤܗlVvvhb'iȣ{ Aɘe Qon MҷdXMk7Q6Z:&f Ud~9՝ʠMf,pc(7\8ے(LT̴J`s,3u̡մ]C%<-I*TZY[lt|p4&ԪU-1 /Ra'"2hHYdv[rN~S"R[ݐ0$qq+=p/K>mt:hGuevvJm#8K2WЗhxywȾq%2.QhSK} 7Ztm#ك_aN=s(H0Œ^Rɠ$1 DKB]HokFNUs)JO#vXiErę<$0Xi*\2OKth |Џ}>|Ɛm\f(̫WA\HG :u9/Lo iS-]$?Ԓ -ʍ-a`DaK·U!v(2{VVYo#PrJ*S dyrX$cIC=ڥgd B!Ll>MN֏|O1ʅl]P.4cU7×1H%ғx@5Z򲐰nL.Φ,6 W|B n ac]Tf]VFPSca6[W׽0ex$j 6tժ$j3$>ˆn 4,.R=r4^Ii\ ${Ԉ6iGUW3lN)1}r/vLTQ#P$=2utWDW˾pJ*x*n&εcDÜdŁv@0ŏJ(^ 6=n _ TvGaD.rB"(F}FS4u*z; J?}~ _5׀Kc?ӟxO~I cg&>ߐrhbބŲWg{U \ VtԗUφL#gSX|n;j@Z6uCŇ;f53Yvs=LB; p,:nUx׮XSrPc\G7ůfu)S aӨ9L?%EfLHtۣ/ }]^z֡}+=γ40TmU6ޢ? "?k]8z>?*1BxV (p&LG"5~!/d3)R+TFEI;n)ʔ%R1N6uOXX8x4nh/}O_\g -8]ձ^E&Kj[4Kܱ"J ]rMX$)n3=-.^|mK9*\k:hͰ{_ hw)(H句|XPJT^XBڝORYc^O%l঍C)^n3bd=o}|b9" 9օ~۹2~x}SIb6Y-xǔ2l^:_-ٷVQD+x`|_1GHpw[V෪ ˺=:jmFajZER6(40974]hXcDh~oVaw!1y?(Nh7Fa?=U j)E"\ŞF[] ʣ^5OטdIq=bA8h 78ϛ+R#k+Č4d<@JxC(9YT:^ ]ץ͓5* +&E#_ảaS 6%"$:@+8Wqfu!f7dCYfi7W1."*#4`Ms\4X#)<ؿf_I£ٯZjBx>9bl (϶豢;D8aip&,59* Ɂ|ya- #yyxWlY%M9>R? :@ӑK|G$W,ka:}GtW}t%ayq7{r+ʓƭfB1A D`2͖gH6BqR͵ 7Y"`|YAbnDeF/+E|{ X{Vq]pD;e_ۼFc\"咧 V;Q:Ba0aR1!#O ì9@ S~{j$(ٱ;vxsnJО$"t7r} q8+$__j6;=(^>XLŪ;8 Iw6#jbE9Y,+ ϕ6e &R$cRwVUQs 4jyw͇eT H[dJ3](C :'ߙ>mYU<.:`?hJF̧=dg9>_?݇{"߼*\燬>~湺 3M gG|kqwIfN鈦GV6RL7U]v )pF&؞hmaC\‚dԻNäD[,rIi̢Y .Xiw%]PΙ eѱSD|ѐ/Wgk }# FNq<ɯsrV 1vO/ՒR_ft %m`c>~9`_~>YCRxh \6pAhH*kYavdt T#ǘ<+R>\GA`ߛFWSM"j[gb C߰KQ ~v6ý2(*=ܝPT)smV. _tu_™|ZQvwesڂ|;3{|uNWk?iӓv6G5 }!VH d< b 1TLL6UU"7s7gq Ǜ}z;)q%Zbj> \J,E)1܏hFyq$MFj"g1vܒʑ,|ƈ)(@\Z}*A &iygc&*qlKQNŘ=W1jugɚݫTx@׍cC3~9W^_w0 B,TM&Ar;{{&gU2YI@d%p<;`4].t"TjO 5hyx)$+IyFj⮂2$N[H&-ZTgid|?PϜ=`S7 xt[XL*gDZ_ 7#Azנ'UkaBS1e[{=U\ '1*}vJ-cr:i MaepX$*%6M , +O0HaXQ*X&gAY1B V血}8=.UľCӷ& )FΦK7MWNL>*|t^ދLyi}ɺG9F3L]q۴'KGŽ&JP#] M:8u!掬|#`^CpvoB$1G\y =?i*vN0p ?t=*G;t ?3.{ JA^Ŵ,`Gx6&W"Hp4ȞN @év_=e"rwSUɐlkdF$vW%@#U0 )F g!M@inJXQND.sse漄k #*$JvP,!3a"IUgjt4v{--ī`3V(6YG$T W_ ʀKN#]:Pm\)~XN^|evIr _Imc§Q3Ϡc46y&nJ|AKf^/dwͿ& 4nYƒ>Q`1ԊOy:21)M7:"G7Ԩ&Vu|n<60pnCCjYpTrp-vTP*5K{>sptԡwF?ii"(ˆ_v"K=s7߲s欙OcTxLu/xt-+6`IDL|Zr)u6F7Еq|;0A$Xmaͫ9Q޾xK/+F>F-BBi6 hj[FqƏb9"B}]_6hnNw1Hּ!߷c/oGmSO?pYS`ϋӁW+kTVM|P DԆ FYYO]VOD*&ϱ,f \ ehe7`+8< 1A?vQg^$ ,kR6Ғuu?l:BL9bRr'@äI|}6Y/ծ0rU O-%}Z' )11[0+3("1xiL5Cdu*]5x G9_{D:X8N_\\ShxN<2"~<VlmXcvw1t5ɶshLeGu?z)0nhRq.0lĒ\ 䲸 fkJzɩ葘kKfQk-,r.ϓE+eޭy'._xxsqdWR18p!S1R;)IcqCZ Me{D/}B>3՝#&ۤ(pX4.BdCY,pX\.}Nԗ_aʡ|Sl 0O"3&$mR9Ϯj7϶_].>QĜ-Rl4)Ihw].l ]tU1giק_^9SES5G8B3N5lѶA,7 HMi*KpJTjL0 Ȯk+ϺXCTܵf .Kc $jfg3Yޚ=2pv? @Bٸ"+]v x]V "EęMSF , 0(.Tgmѵ6g%aH.S [Mo da8|oO6`ee7YF< Ii2~ji֦:#z)O-h'HSy"vO]m-E,Ф UcCEwlB4h@˗ `+ 5 mϰ%h)^8\EG*H^tn6/j KIENDB`gift-0.2.0/testdata/dst_colorize.png000066400000000000000000000643631513354670200175030ustar00rootroot00000000000000PNG  IHDRxԅOhIDATx\Y-ّ/_>lSg3H&),%$H+ B  p[ ~Ch/݀ EC ,UYL1+Lf2ǘ#n&"ٱr[f}-}? 8RmaW*º>5f* 5r V*i PQFWxzC4PJGрI"HSLWg}uӜ{osrWKе05_ CWKNsr`2ֵwd/݂w'?{>I[QVu}nm))潍/_yۺ>77?I-4͜pATQnaԾo@] PZd}Mom{Ba{Yve<~w~zqK~ݏX[!V3ⅎĂXVzgp0J4oȼ&0tw7N8VYsvV70z}k;6ƪֆ+ JB6wGӔ+ oy~/._|շdhmE10nʯ^͒d(^bTQuc=Sz49A)U;;w=]꽉kX֘1(Z{\IbN]WqYEU Z\Gmi7x۹|IZ= ʆ7d-J%J5]5۷'wG#}xX}ż,k o i|oo\py*0,C<1}+lx~}{^IflL ?wLݛ7{{{O~\g/vaQifEK{_5t K~ZJZ%pȲXX*cVIr֭f~||V1dBv\} ?O6D‹2an XbouzZs,WlQ6~OCo"2#&/ `7qVEajjz0u{{AɁ%=`gW:w7ONOՃ-|h8`9ЦTuE9 Î 2fzu(ϲᛣ[E0²=Z}6R{,$ϯkJ]YQE9 \gйk%}J+x꽣͖'fNO?6fF 4m;:ûw66̲hAh,¾Ε/ppxg>54=:g{]4{dd9G r #6l׌Cd<׮e)n\C|com(!zVh J MduN;gWfo9|b/`[98(HļH;_呵(hICvynVa]Kӝ(;aL0J$ɤ]P$[)[UGߜ)֮e=x3Z43R='dR)=t޲>4혷l>M>$~}F,mQXk}SBsXXˈ۬lC4c (p~D}5޷pxwoo޺_>y! 㲴&CL%Yv֭_ϟ?YN8FQ.+ˣ `/r Jy~GICJ\8ȲkЯG77$QШz{0…<<9Kcy~';?0q@ӯ*s]Q~p%M2Ba\zjZ҆MR"D280Y;WvVkgb0ѫS󺎼/)+l78 w(c6X\܆e̕j-,2aޔv\}h'tVEYUrpx'ˮrtc(β#{XX hmIڴ{بM@!L,( +zNbf5fI¹z0 8>:0L)OIʜ 4sZd[T%'l$'DdOAtV~0/g,SsX *QFQl=a!?eKhtǡ@`EQ$*I>Lw[z d6kU( abpfOYobt0Xq`!P O#f 9MYqz4qk!aXr.ꛦY,`?I ȑAHFZ*>f4jqQ6Mdv [uLӍ{{;IW_-QDf?jReB!Fp\ }/;"nm #qiZB ueifࠬy77z۽+ʕt{;NZ.pӲ|\D3fP&ZHܛ [kI [=DjVoZa'WE,'Nr=W0G[_\D0MqIa %4X0 % K27{x}pw7,f>o1sL'͛ihk+؈T}_/Bϼ{O*hC-/a YGQWY`_1Ku}d%KYЃQ;sƬfAi ?'Rm+Z=8=(I~TXU65P{2_GZ͟h^[@78/kw,xMt ~%D0oHSeQ*|ǭHkO Qn/y}rϛ4mQ!y.xco/JF#@Z]>'O5D6'_@!qw ΥTEZ[o: ]M Q O9cmǥ j(k{q\ii4<@& JV?6AyEׯ8(,y .c}\nec3RP* l ǭ QF0 c[p݅R|L]ˊfY}pjE\͛y*OqI{QX=TVpx̴*,=VEaF̤Rpx Js)DP{Xt`Eʪ3{`'L%=!' r&β=7n`{;V=<8E@7( 9 >2VH0 ^cMI^ YYF)؇!EnI,B9}{{i]U-{w7,^:BƇU\G|*) aX#DMEjJ;w&IET5% )i= $I҂dJ(ʽo4R?4ZĘyw9ce7x3xt8-D:!31 )̋ M$iCIEy~FQLn q-:ρ$GYJ\ɞ>]߼9l7JFqhC͚99^ZY.i'c>!UQt-I^$Lwn_ m}l5#]-X&r7/QUɰJ4CMr+h``Gр`$IB){ƍ|s3β, \ Xԅaj nMX\^?-W;aXSW^T}E4"?QE~Ѻt8:\gg?ϋW IL !WcBy۵BރA)8hB8Bm|1sl#iz*5C{?Wk]8#E?-eG2*>A\\4fᇻZF!!i1GEXsk|0Z;=<|ٳϝ+!t3vJfUuxX[hʔ:As{,%-kt>q ڡ 79q#u+_\4GGգG%S]zJ&( 7tσbߒ8l:08 bqpFi(7 1!2Tl2CpأG?B.,DcRWmrZ8JN$e O%#Z?Onȵʦi404 _# /ʊd79V6 :W9Wrubu>xTF \+AYFU5MCv7Y~vӻwǨ5'ndb`QH:*'ksfF VW[Ƚx"^C\PIlkyǨo<׋H)k#H&U5`p.5QثχolCih,{ï`V᩻AkѾH ^TEϢ(K$Pd4Uu:D=$QOׯӧNLK$&2+( zBJac\ƃA45{F:4ʵN%=t1)jt:֔ @e(!6hH한TAln&e鐫'j\/چf2I6~ַtSI Ν<|q* pabU*U]UQ٘NcP< IUe)˥㐄9?(t# "M,A]~/! N.,$0XZ-N!(>0^YC!=W T &e!O PT,fM",>fam0t vc?qνN8CGgg5VA - Tˆ9+GF(Kh eW`dz,)m$$e6p-H[UG'x~mX. 5bтq<$A-~Zl,w3==^ϙ}b9-Lz6`$Miz,ˮ-T9X)AӄJ9dZ"ώ{f`&X; NC"f9BpVJy(jDp 5[5 T!!hZD-;]U ːz=d򸣝䤵 9t!hG]QNO+W;|ro0@(po_2hvuJ7ؘ.h=FrWΕɷwv~{ΘIbݮIQC (PvwJ<6m==IZEj0=dʧi1P$@ [Z)%woMI EiTV`.p*DJd ؝̉]~ac@ vk+5}٬߮!%%9S]kHJĠ[[W={li '&kE 4]:8 cHDMsEEU.;uݺjHgXU"Avs!Km]"eB!9zmʭF"\*9x~EA d*\2V!4KeG} AL{+vxpI|xXfi{ *҈/>4gT1U*s-.|>7ؐ[ÿ?ƧE]-Դ5H (]7j6$;^}L}Áb+ H-L, 1<*T& s(|)[TC1u+,baABi@lb#hwq+/1t4𡽋 &cnBn@Tε sOPZ:9INGJvv( zk$J4}879<8>ӆA@ HEbڵ1볳w7WGgghb8/"UUjZu.C; ڴ %h9+YUjӒk3Bh`,sjevvR`^4H@Q"+7Ƙt#_u~^ 6x'7F?9&v4^J!~t?D!(x]dVavUVJ_F oA\XOh<yu.8=$QG%Ű>R:Ȳmc | r/=*8h"̕nR4v-[|h/&57ppޛdbu0,ɤ D!un+ֹ૯˞)HA|wd>_,F}K]vm̼,_T[fg(l7WIB2'MV]dd>!#)쉧VM$]vzu%(a*V`7w!1E+k[:Z/ˍ򆍍+ +)-l`mǃeAn??ozY[4p1ppEaW+ݿzm Բ0|z\ӕ",5``t<>8&I6,S\{;thxfp& kU 0|hq-0SEvaI'P\FVO@LܠuQTV(ٳbg',>\C<1x߸1e`aF~.{PΣ(iO9sk׋7JxzHj(‘RwbzW>`cg'޲+aΔFܖUyƠr`)}]Ww} X+n3,H_mOˊfT5M>;;I 3Kش0Tz<~7iS yܝ)qn]G AţGޛebЏ;pbIL$hVpR#$8elJ/VxN$ ;A +6i}1%rWU劢aEӧW31M@1o_,Lӟ$ toFŞvM3_,z$;i3ލ1&L.`g;nn&=sOR @DV*FK;B@Ϟ [a/HrEz=spuJDޣu4M*<g,hؽs"mY5AAhIzU8#==͋G^[n)WdMӅ׳:"`:Mw4tzE4A>9>iӜnngٕ, 'ɦ֣8\uD QBR,Ě⯂6:QKyd7A>qJũf%KR\=B,Œ"QTΌ.s"p%职@2jp_hVڵp% ٳFF KE MY۷n>i,΢۷aPEfGs9 T{?8X,r5=+;U ~؛i>Y($8\*hVD$m h䁆^t87áHv>oއY'SHsUQq.qQ @DT'Ȑ!FAPYNN~e]7wAP(Y/󯜫dPD^7TiCM|ޥGؑ^ȢINZ ZG7Ge"Ru]Kem!9]LS-J0]½}_Bq$LqF(,D5{MX,ƷoorKku^maiYZlK\~3#Cm>X[*duk=v@&ox89Vz@8  P^R! o~3?;⢡QfJ4qtUa<@*0. aˬy͋c/SH8=Շ ɐHLr;?oMk:EMurRZMgagNN~XonƴݩlyrO1Oy@s'ShxHNЛ7, K1$LwNtFꦧ 98cRd=,W@q Uzb{ @hq@y<;_޻x88(Vx 7;$X!K.4w 0: aJ% @ε[cjeNN$熤Lz<''je&^fQ^kn*8W蜎wC)l5#'d~BHݰju|q1`20! wYv5=n8T+R[[ )S*X/y$<cQ%lU4!rVZ,LY<ϛՏ~ .q4a\2[ % mF{ع<SQdCdLnwubV@8FTVtq66])I: yei'|'ei6Xã|2v4ê>')OU_d&EOI zc#`g<$nKWv㍞0T*ڔ%aIĞ 'D]EٳEGo9nx4jrik_^7k[t7JYtgggGGݑ*e~ m=mx6j 7M1h`UKP}U _Ol' r>}Z@Q$ͪrGGՋzm;7мva< K I&&5J;;)ڽ(9o?ѣg彞 0-!0tO&qEE㣣43Ѝ!<譪Zs‚ 0Y2dD­u*h;9?i:M6V/^y7.\.'sNzf>Dׯ_))ڢHϗ, +/LrlI^``1O7c"q %ݼFegwn2Dd6kVb֣:!r8+6׿~ʧ7( 7FhSBX4|Nw÷ cmrOS]/ק݃D85|VQiB+NܷjeI:b($?|x61[n@}i( IoꯎYFJTIqJNY}rRyU'Oׯ_E*ܾ`8z s4 1qZiԫkf8ɰ~X/,wKCec2 |"W霩$BK~XD9=O~{ׯgi2ŋ&a}(gԒuqHqފVBVGic_OZ̝yM0 (G!aZ%2^Zƍ_95`;nlFQUgIɓNַ&ׯg}ի!lǺhRU(&kmWrբTM2v^ZUnM㰝A< rb`%fQ*l=5'Ldkg4w\rBk}Շ?}ok+Ĺٳ;w_tD4H}/E5á?~cE 5W>(R{,%gޠ1|N 퍢<::]޸4 /#c&Y?_{o9Bdc#}{o''aya-'}0:Y PǂM6lh.kǍ$!/#.aap]* }ê,k&b?wvK6`(W]ѠM hgv/u}𰼸WGo>;>L0ULi*vС'Cdw>K>g#:N>PMI (1hy=\gg?4%cɴQ>9wvW( o>p{{;zp_xQ+(ef2芆A"MQvEv 0TM:RfZJ76) [UG]z|^"OLJ]Iʭa8?1J9Ը FG1}Y}ӧR* $٦*)X ŴBxKI:> gYa\ Fm=5|Nɝ;׳/j>v4H$Mb.t6eWsIkadsFM`>/WMl3kȝy#Yf4!tY/.=^A@3Qṁ)5>Cl<-[2_KF︱ʓn!&{WU i66( G#=ÇZ=:R1 tbL4K1ԡhyӜO&.5O94s6,?M[PU]Z'O֏G>>#)Y[VYp8\fP@yl"# JU9[Zm4M7V+ZڒĹkZs촮Oew]~Օ A lkc#>, Wj o w T#0,5C`6I0ggW1 D{Km+DW $p>2Mw1X_i{0qϞ4$ i?;:=V+Z4&r(`kK Ԓ(de 5 /[X)(RV0>!F-{^'tZP^ҟa̚B@'5`_4I>j6k[15;cV֮dkc#Yn9Hӟ11!>~W`? [oVHigLҘsNy6͂bj (ֽ[Ѵa,&q8Gg8HWi]U[gg..b һכU[Uq<~?&оŅrNGyx͉ĘZ9(f_ q$jcWn<{zcZ I27 'WtCW'YvK!E£Gr-E/H{c0~(v{^;dHO(x ݵљQ8-&''zzH8(O1GRMn`#1CX@dgNpRD#5CaP[/FOfI4͛wyѪ( ̤amqxg|V+Ne5;5tm@+%Jf^vahwihw>/ƬYfVnCF$Cmq|6FCnll$u^,ڵoj{;Mo>a߾=Y,H4 Bu퐖AHctSs|iT  34EBC}P4z'vIsY-`u}x2w6?r+6 ſytI*0R1'`O`2Nb&| Z>&*􏑠V8" "FkIUuWяh0u}zի䶐Z j>OhA>6see7L׎U,hg'ECl"1N;<ē$ٖKL%I2hx8VM+:$ -yɏisK:b4s9|Zp)2_^:|=46%!޷;wi\=i`8 l==Z&ˢ>ظ~=;:ٴի,zqYSFOϫ?z]nYDȘo'S1,$'W!ϲxa)Hej34hP#`o]e n<-NO9͛:?tMx#Mû[[#A40fvPr0u 5&}ʧ;|kw!jZȇӆxp5&F/nN@U*o4yE4H sJ{oux/8* ^Lq,ѽO\XN}e]v+Xe(wei HWX#SP*##fiMSzԀn̳LUMs>o\t2錆c|*0YR(dt@NɈ(%Ǒx"Q ?Z9;hP 1X;Ç޿6ԣE/}_w&9=4<9PhVkrYp% f!hrdYF2k=ŋ3^߽;4ު4ݮN>oĄFǷn$qX;W7zi4I67N&Ib1K:;Zl'$8<.gA(ݨd !6*>Jϝǀd߳ Þ2̲DȁZ ԗ_ώ>;0fA7 irCnA2m%b*(jJ/UW8 %!ѓ$ ё'7q͚>Mb~;5ϫ!sw)KʁL̔[(cwf+A 1_(2À3iΓM9q9\,V$ 鰦xֺTߞ翖YlP\os4$瘐QD (fP@Y.e,lS+,Ă~{Gt%MO~O1Qdo/n̹2ICѣ_wZ^YÇ= ]x1G7{z,%Y@OG\Dqn"RgE1k\VD^. m̈2Oz}?oDM(icc$+_M>?(Iө\%e|Qr p7WD e0`U֫Y+?ɣvY/%F4M1fcG݄N8ClDyLj]BXљnXr'AVky S D8d7834ȳ{b1%ҹR1QUe9(K7}?-> U/YN]uYIg`JU!"!l:n&~*~k*\:+DjxI8 &IF))?O*ă- w/.~)\D%[W`V9Ba/[q) BŢnEQ<[U&,S9/Q5 iǧA( v\Ӥu= spP\>(8M2I!)rPeGyJ*^& "uSB Y#-_&[=ϷϐJUa&<=!&DJN 6jI b`8XX4|cX rWF3DpPnPcO@$MeE*,/MELVKԊ!|k+j8 z'˫~pbIc ^_+z[!r<AH e$ڹBf)hjHae ;Dw2hk=aKA`e蓆)::"uhmw `v\ϒ9~C'FLf'!Ul/㎤"l$/i^^B;u}ʑ#4zY,*gOtii\.IPvn z)#*1mAThh#GGb°fNPa$=w8F=Q8<#j^2?qW9lVO{TN th fF%B*Oxq1SED 00Z_&? 8MHr?}iCl3 Ys 'w⮦GDw˔Ƣ|:_0-pQMN{'Dcz}fѻcr=MS܌d{;,moPkHFb9q3uMj+n9aWD1 OV5Α˿2zFIQyR_P31h!y'0ei3gQ*:! u ,4X7 '!Jp Q9P]VzdʱxW1}4+vV?䱨@!0 }JrlM<Ǩ T- d An =_"ܒc05xjb9H]a ̫HJΓd8>k̚Rֵshq,)_ !m4_Uu|~SO.Y"fk y Z"`vHF b=9J9 5Խy$`+DK'Կ]@'sBfLԵKO#Ō. cf,5K-pS2 RPYD(kB[6wtUurq18e]=)!,nD׆ ;q80-r T"1c^/=?qٯ&1 GSwLF ŽJF.%)]wG1EXLTvש8vbf>;h*; zY\qA#iDkWD*#.x@[7f֢\^T+sXL֣CH^ ^h;{_8Ӄ-~[=*L۳Ϗ8}YR5`PXE!w ,ܚ)ט.Wl7\P"Z 2Oнy΁HħA!Oy2UuRUd k23_A rC!1ÚBvH_ /-Hא(yswtYZYM9qL'i82 w*(F RS\UG*!zYȰgBVs rJE {iCʻB'a@qu3-IzZ"ߪeܰU+.w8@:=0Q=/ FҨީx/A /I ٳuB DlbRLyNhSy G >oUF-~u`2:vGbC{ZPi{Ja5 p:+C(%ʴ$Iߚm2*/aQ!?#**˅<-u>]W "sDZ]bnln[[l<\#qmt )xw%` ng@R\' z{+j})l75')k-QTg̼h*7.AB, i2#+ Hr,W3T V<=սЖpF;B#eOY,#,=#bPA vAIc #u.&nŇ_v to9xkq㺲VEy_)y6ndNpVmʆ`R"v/뢁ޮ dgӘqaI\NdRBA"OVm kAUg<[,Ri߼~=j[; <;)i.mqL>q թnv`;سpL/@J/ȇma OT"!"z@ ' "d9DUNh[Tc*p:iy~S0Ʊ:!VC P/?1U^0 :rVx%N,;&_9f^AN٨ j^l9< %xq$P~+5]6d~6Hoߥze3jCD:Y3i^X}9h(O6ZD߳*6cLCg:T_ 3^wChWvBά,8vEo@JCj{/N)0MÅ6~dk7C4GX9{mB{}γiQK|ӽ?C5 B\x6pl LT'{<jxTY'rwP;K! 3ˈI6 ERtvk0~cc{ؒ h*K=ΕwS@KSvXS |pq` r>ߕ5`Q볱0 tobyO cX<6R[jxk0#Q-s斶-9=u|ac 1h2)@[t<1lF1@z>wHٵn>X fN8Cu#÷WvGڕl<졏CK_ѭR U1UgP>@0/aq)^˲<| \.?==%ɺLCALj0iA$\ٟ/N Q! j&;m@"lr~'&: `BE@dë7%߹d6 }ʋ˦[4,351] әxbܣZղ /(uJR]bw(;`JCbqqv&h!|<„0Av;c@ 7-e+.n!bf|>naxrΝ!,фMӤ02&$AY6տІ4D ܙ6qg ,Azۮn7>uj8# e>?a}?w>pqÒӋyt<<|(Q[oDn媧|i9h:@aj ^Aqe0 Q`A'g¶:;$([F{4k,դ/:Δ,PB&~af0{NsT l3FΘC/zp55a?|͈2#S ]ZBA[sΞnך\h є}_SITy~'S`bw4-/>Esy7o7NSa";zO'&9:<tKvIA{Bˑ(+09l̏Er1\ ?jĩ>o՟ݼP@oA=PᐧvE"Ù<`QJbhd},fB9~n`ljԊS"LAԆkv,mVhrr; =GƄD +qQc y5*ؽaˀ vBcD }beewJ?h#jD8 +'Y, Vx{|D&1`9 FI7ZdUMN򵫺%Q L-.̔Gqykn?es-WPuYX#a&q!SϮQ;4bچm&|GZ$Wv `X6j p@`N[4FƉHvtзnSyx(9)H\bn/(w<y3Чt%W #z9N;=s@O&4^ i'_fǭSsCF ]` z,TQO7 iI`iU abk5L*`vHb M&ҺkU$Im Ml# `F a54AGy\CJ 6 3D>W8Sp(=a`%0xx68H3_ԛgPluS+M%>ƅ(ޛ6[XQY+\=~H'&%Є4㲹Ḙ߮?+pT<%zQض+%׀eTxOӹv>o m/(2Hxa D@ |vW%NYMI7!m9cb$\Qѡ,<; @Xp%n::Ё<4wn"ⳋc@+ap <Ę=J}QŨإt bg $a (؀ߴ5ܸmKḳ_/NjZ/02^Xj @G,unK߃3X&: Ruv kU&ww&"{v}JNMJ#U2PZ2L0 K`캟ܸ/bNᐭZ@t&Bwmf\^E$aYwo,?X=\oC80+|J3:6vŇL^h}ݦ1mn}8Gm eY6ٽC><[Er5$' Edr eVq RhFEۓ\ ڭarHm0bV#?2`QEѡ@@""U>G;wޔ:\n nLaj N9QekI[:Ef;뤈n64=ܳDJ*#Jjs}X`;XAMva]Nwe_ou @XbYK] a F/(XH z-r9ĢJXlX^*;ّ_5߼|]vxIxҧ8U=l"8;ON,y"iwן_ ^v)E`HoџT&_."߽}8A9o8vb21FZ2(h#N>m# (5إHs3_ն Yjx0pvt>n۱4% Let['.˦CA~'oV^ecwm꺭ڀag`1s\v7NBT[ȝZ.57/,"Nb+y+ob^ANj:`o@uvoĖg#eH``|}UKϟ$$߭-Xv~4mpဇ|cg_2eqej+`Q-C41 PGl3پX֕Λ %e GxCW]wQ$o^/-Fzុmau7 X9Yda9kyflЮM1n/_Q,$ߪ49t`7duq:;J|p-P̐1.vdur}|p62Sc0R0sU낷.rx3)5Szpz(@ofU%Ꜭ-?;lȘywH!cwԩ&&%!#) +erU]{qA RL޾ɣ~b7Ʊ-;ɿ}Ex^ɣ߽w{sx@5xWD6ɭƵE̜^W?;Wu݀gOV痫y]C]7u6,Gˑq8tn}W7˦^MO_+뽤@1J25օl[ 1E. VA1yBj6[fPLc. "XvN' (5mgZ8]u)bf etmttr\,K-8gOW)\K o=]q%SR>iK/fg% H*3(>sΥ_5Woɘu[spy_N/f᭧T@&eo|voo㰘?B˻oiC=}U,ɤel0"kUְ͡Ad 1<%@JA V m3qLqY8/gR4ve0pT9G#my/;-Ojf4S"Ôl  h>a3ƲrP 9+@Mt6EBfP@w+p=OLwoNfg<~v<;*:C &O5DHiȠ(ë0ZY]ֻ͚oߪӀ(%&{\[,v}JЭ8]Jٶ|%IX1$]VA\KvK!khjdS':'f|ў/>{~+̞izfuZdjьXbpzL6'YhZ8mnϖdy֍]Lm& XX6TI[gC5\&iWEJ =em&h7,(Sdoe8>ABJ4h ɺJ)!H# b4F#r'D|檘xpwB];m|J#s,n6*&ԁU=M4V#2]o{ݶN..S4NL)ġ,TfdoB3gK$ CUNt8G* 4ֹ 4 ƶ"\Tr`l6_W8p@^()$BgYGju2lw>ϯ6e`f5;|(ْA3fF%N*HL9i$0;_6 qֺ[PL"bB69N TJ_K|&c(Q+!5JXGBWz)8CSVfQQ\q2ؿ| mt~gf+v%IՄK$?e셾 /+X6D768WVg-R -K\^ryr841tOJ욯׳ʇ:'ɬӷvvrypp`%kT%(d IȻV,Plea lq> NbIՓ5Wʘd^q$ qJk o,9vDɐ415Mhۻ..VvQEL Vnj^Rd2cGa>}=?9lgKBY%?a^Tr ;i*qM0k ʫ٪iZCJ pIN7_z[P]b E9UF|IɆ0GZ$(N4H"ADFҷLQ\'*P'Popv*OYVTkyyHNbmp~yz1TM뽏To-I(&sGSYo|k8:0H $^0ʞ^<{wߌZW̻]y5}EvZ"_ǚ8Kyqf rLpٟ Q}[UT#0ES CD:@HZ"hua@2qeo!Dtƹ4??86HKI@V3"9Bb`9cl|BLjpP2Σ j!cTM. 2(o!kERwA͚g4 ީUҙRS3+\5U&`1}껟?ޭqLQjw+$belS䑁D]}bIƎ wzimFHK\1퍧Rc1|sTX k]ʫ0TKuqdIcݝONΟ@V7cΕWi;QE> 6 >uiLUJ7,Ju(Bs_~1J}:Q-I>N੒,d[M'E4*s4@Ճ@ħq~PjS4?'溻P".Pc |p <5ͦ\Ycg#D){#gm ;*dd $j@e3`~WOTWn} DB dcXQ095>TiU25V[g2,y3!*/ňԖ*?r~c)}YJ&~RAAhVQ&T+3j~f~ \Є1DG*e^1Cڮf؞=ܶ݋+̇VI9C%:9>9*I!8q߬M)yȩA4sAE!yƬ"R2Cd83`MɧKq/N/xPHR`U+jlcR-s*uk'RFE=6ʀ5}Q~i̘ۻɑA^!J9|zo+%M[_Xsvfg{s͑SMR|qE& ٱ% G4ȑ(jEr#" ۊ; e%FU[5T/.ݛWeT7<1Pj۪t2hrHIhBC`aQΧ_'XA'/tYL &/z}# Qb8g٘Dk+Vu@RWQ)f*rIêg0uj8tU>bb ؤ@*ߤ|SL~x. }3[ݽ~Qؕt!& p:o䵭8'D 'i8+SnV*+ʮ;GAG>KUƥP*AFkgypK˱^q,f`X ؂-IJ>4*[,Ji':+Z5-wXwPCm,@S$ PK`4Mcy狒}N^ @B)|e{u@@]w6OMh j5OKXeNX ./I%FܽaNMۮBhTS:DF,${ږ썳uO\1[!"iApGbrE竕 ,kDzHh jJ7N54*xdxS?OEHWk\z7{0ɐӫé-+UG+E |FKŠ)u)l4HPW" q q,G0Z "$ t~> v¬:Θn^2Ӟ̭Yأmw;6{7_W,I զe|sğlOBծ4LЩO,r[냯j"Ap.X6gl\FHMqR؂r@4 :TsЪHU\2PlgU<ٗ )nV)Wډ2ps1[5E4 1Hq~kj2V2)f$rF&1ݸ<[jФi{ι:È ˧}9qU|01faye*0 0Qw@URid /H($:ߡ EK`)Q2R'>fQLH=; Enw qQyvnMhHŠyg1IF<ΛItYaQsj'V Ex ,XH27rF봥#ݮϠקNGLJHNoPeyQ;m" {ܕ1Z9pg{nj%".dNA~{}s=CBu}KFB8Ę-QҙFkUˉ:d(JBGK*`kuRL-+-Fϝ$ Y$z̦8"p+ ΧDIV``qA;ep# MUJ[\]0j&nA:$j*clbc }Mh3`[{mH}dz{gOCDhf¤Er*ԍoN'_jGXkmJr8vnӄd) Cwݰu#x"嵲T2*ٲ`l"qN}톧*S#0jfm8˝c- &A #%rrZ-*L)ZJ&2B#5JI[1L݈8618gkh$3&2ǝ꽔LImb*%H4z YvG MS p- 36WYכPSm1*IdrEH.Ԯ!Qо߼߾nΗU()N}]߿H_S*~'_cnX׌i%H Śa~8z||DVXN.Yu/X^r7;ljBP|9%LaԺKe9a4,ijʤJZ@(<6Ljs%AryS) ʇ>Ch?3s"uaѬa8X/jFzwα=2>p >XWF!i6|6_"*ub"[bV-b=+|4T+K#V1! 9_4 co3 KAބ,YneU8Ky e)D%֊+=M[TIjiQE}U;茋]Hn|]YZ,L l< #R{H )P#!u׻Vud8z&:$Glo'O$є#"mm&xJK)[c`R,EKUQDNE6;*<jai>ԩE?(GRjUe9}xlq~|aY@}>H%vc ZV']쒲{lc嘲~`|5mgu[R\jˠ-<`@`RˆNQDHk aK;&PF$:[,߿yƽWkc1'Cm:r RpsbHք_x5Me*dhuGNJW2Ți9rf؇q4y~B]`JT"Ωn^<:ω%%E{y$3-c/0[tsp{{ &XO@qzqCxiWz4t"ɋzvt~9&>KJ?DI {J=}4]! )EsͰaQBi$5FM؅˹B$EQMC+Hޥt7eȹ`ƒd,/mOI^cKveslН&jGVe; p`-QW P2|L>QZCV$OR,m9+l5PKxY{Srz-w)!̖#C %O3Ҹ#m<%:DHNzGMgp IHW>m1Dc0nvnf1;3R.LkdՐ윥DŌKI)%l! Tǀ)~l2 p:kxD3ImJoeƬ`)Àˮb*q_ÿÎRqs/?3ʞĉC韌i `p6jY߉7H+#B*c YIMՅ嘾iTUhBi;ȷ4,y& iV{ ytD7/?€c52-w׫/H)*I&+0ʻ}Uuadkt|]c  k\+ (t:2>)sk3%& 5fUE۝ !4 8(5/m9[g' }|rnu:M'N8=ap{aR&na%PFh\a0ډS"J9 O.T"Lmnv~T|,!Ywh#jHIwU ͺ?l.Vˈ1bR 33E(*AQpf~ 1,BZVU]5UUuX_Sf[h6~:@eeW}́dʈkZ7H=coX~bY-|ݘ?OypJ/Ʈ:x{be}}>Z-"RG:*@vN+Ph?5HQ9)Lh,|L3P8!dWM@q Hb3"Rm|1CN)8,])Rz9,QnC_5@aƄAh?1B߾i|QjJۿe΄ !T .latď楡(YW6(VRSL{Y9'$,[FvT ,û_V=|hC{/rΞ4 8dL08 8 h-,?trYWeG4S3.1 Qdj +L*0Yd U#%LI E텈Saf>aD x_3`w&l:lGH)"94%{!̮/C/cH;R=yO v%:U'[t ggY/ (C۽5!#1!EE.x}4$Dݽ_.@6|05M]mO xmgl,3AKX=O`ufwW*AroYy=TY/n][pCW~ B7Af>ye@ Թ)c\|zTi?r42 [b=:fY&H9o,942(L ˀjt!'fyHC%x܏Cy5sf_R`.9cx>o_rg?E=88և'zdp{w=nٻV]:@ĺLB)fɞSM]i72|1H$z/)"zICy bf>N2PX3>=珡쯿۫yDBlCU%8R,@į@VtYpRdɻ2j- E " Ny- vvW|}e]H?nJvdCҗ7|uz71v{{>??t7`;Je:/I-nOj=ߙ㛿{+AL;B{N|2 J3Ck܅co_..~ l. X_իz>?yOGGtqV~M7 `Lh1y'uPs(Rʯ%S.=g;ņ/PEhrbXevN::M()#Fs=0rL:rvֻGO /-!!IQ`(U_.O_nΫ۷o^w&۰R*͛,ϱ,% GQ`SJO_aEge0wgET͹H*)1},WnRz;IVfZd20@n}'PWs?pKu_^bozJ2b?؝D&La!b6tU4آt9It2BXb+ ΙHc?īD8bL8$Oࡎa<99wbx.1cN'H`E>I+3~/n}Q T$î qt?v^KRYoe8x֕6)Ss ЏQ:0>,ɓiOMw_ qԞIwc9-yf.;z>@s\7o{0D}/qzp)RF/,2HH7͠$,01Τ"D2#1vG2KNhr)(Dǎf!St>?nv^N*j=6g= o4Lg@wyutr`uv8FkF}*#u idSٲ:ڽ|yծ|*SjD$+%;'DՅ7r$<Y5%xv.v_?};e:fz"^T;yT^7CF"C#V'۩"rLEF_Bv:mNNŽ1ZJlDғi)Ɣ#Ź m)h:exGQ&M'{Z3/ӓ  =%!sL_~Ϟ\.xi>p ut6onG菲0SQb`RO"6eB߸iszUaEڂQBpg g {牢&4 C]=Jv~uig[);yȎү}=g;SH GSJ cNx* {h/166yy|9Eft8/SYZ~liR:#n{-FpI ",mm_ c$4˗OǕWW5u )S"cQ6=(i(c!SU˶~`WZ!~|tק(/Mjo(Cd/ys2#yoefHc}n]u1D8R7P/Vpp]NLT9&d 9#7t$66,27FKR2-ڡ_dSW,oeAGm8vK 2BWp %a_E00<`B$(Or&1CmgsOcc1g+hjɣgsZsփH>[3Z^ Ob@Ȍ|cKA@f7rJ@HZI.$LfaKmLwf'tz08gnIfN.էh) &z_|w Mg33:cLysyxzXALkƁk-We8_ǻ}!Lp,hOک[6.{·&ZkĨyH#4жҶ\g+vq$!*rB @W.]؏4R*Pt0ؕ-iYHP!}M qm ǁrZT\ u}4T%ȥDBέͻzCXh`$3'H2v“NquvN`C6m39V[ђ<˪PK`ق!LϴZe/m✙9!ao/~6o~5u@ebe$Wpn/$7-EåOzrQ1] REC V-q/-' {; Y)+nz^~ծׄ\7_qMSZ[OG!ƞ>v]IcN1 p^<'XO= xD!cpeedIzjí댣i4tѱFz0 J)HDv=_Nn' x GKaVucif2D˨d^ ()yrk3#0uQS+GXQeLd Ƴ  ȗ>߭׮5koj^!:C"CbW孩m}8qփ6̧`|zri߼wW͎"ٙOg}ٌq0P<`Ί^*gIz_)SMyp[1:wT&P) FȀW?UZ&G`H?QHd:iɬG5lx|Mߎ-*#,>ǘNw7*CO׿qo,zbyf6V~ESK]AFL`L1 % 6BsK4d̀#=+*#r'k\+mdE5yOCeX iTPTjul>"±6c͙ɢ 1l` }uǃH1 Q$v9e: I&X}&Jr>˄}a~PH',d}ۯlyW}_Zݽ/2عXI-$BB O'ޑx@@vl3xΜ޻{ Uu;G/s^.U%+BHᐩܼ e/~dUmMxWzxpyx??^|HrJݭo^Y-\OKM*[mNIRPiR$m>n0Q\'*ékC`y(F-g:+'tB#bd#pt 7I[y{9=7;zOOS6R~cv20- *ޓ;8qI1_Z(\QL,ީpՍ VZ~]7!C\y|:%K.ot~VDa{?˩1gV]2a߀ψVQE.(Ӏ3Z"[`pW@a!+]`t3J[>M%sWdw;[Jq¸Q;A1 צ=ZjW' Hs&Qb}ߺx"ŵ̇`Us{Fs x=}uUxς܅o/v^'Z_<+`ϥ%.#_Zp 9)"S &%/cE{pWZRFv p|sAx˙H%m2js(9ﶻ ԋ{rłnھز5;ny/-/"]PS&_?{>>`R,|(Ar9zqsl4uY*=WZӰ*V- SG]eRXrFaGW2pn;9bO57_}a`!FKO/6_M@"48J$n]b-z4l2/u<•)s~ :>5k. 4M[رyo { `{tv԰\*aY{SR^O)_М/WZ ૐճf#) 0pGjbw޺ D/@4/EwfiҔ:8͖hM~_>G?wo7GTf ]40 v':zUFļ%1~) 7dCiXv_ak>1D8d*zg!PIm?i˲ӄjTF;i@ eНj?ijrZ,YAߝ05|<Ɵm"XVEsR`X !2̝aP3k10iʘD)vmxC@է| Z-N]|!NtԠoWwANI,K[- .2HO}1X"M"t<)➰̼^N!8c3p.JddP^[%6ӟDDo5^Ο1[0y(}A]tqxx\w:e}*.,_elH-~[)la󇭞4 Ú*7r7(PA%AB% ՄK-:\b^1H=g dȐA3̥ a>?ŗXRo>Ku\l2LmہDl7hkLN]_xbܟ'_cըCMÔBd5zqMsaݷI~`cg?JY@JhSZr\I 5}uz~[RV]xPk@/?x+?Y#vr6 Te 5`MfML8F7t vPD^鰴e9?.o}$|Z:F5z/x b u7 I 2:)g2R3u"kt3vܣۖ.e'١Vj=oO/ s! 9ϵXIMUhqoϟ?|hTP%%lII&9d΄hTj[m,bՈ+ńBY)y$|\]'7$hl$Bߖ/Q Kw>_&N/ټWB!nuxObncd1>wUBfeڦpup!ɔ˾'L7oqe]S䘖CRmѢiZk,5.󿐟Ƙ"W=?-Ϳi^g}Ֆ7CTY#q'^`d I;!@v:^FAW8p-!v٭- zp_Gyi/9Y;?|}xRSS?\ԿNtWk4=N9S<W 7veVK~]>>w/es4`UzX+DkƲnϺO⻯߽*7P_a5- ݶiSL TwwQb.Ȕ0, \+N\GGl !rprK@GH[C,Ꮿ?+Wy Y4T" W=k;}*m|YJ2Ua),][TխnO^{5 USࢆZNv)ܺkHh r-.9_wry+9/ mfg`I{ Pn(-sG*|ALhD6yFp-8^2 L?r-2F9NC@Wu*#5*qնx]˟|uXyE-aePAj-Uԋʂ: J_~ G}.g)׽@6N5WJ ȸ\(MU֛ЎRij<#J-[;F eOOjDB%VSΦEF@E) &w.an7SIZ}mw_CQ8Jm %WZ%?s/bYŽӺ-sVյf/>6u53w^.| mUhdc6|C2Gi/K޶H()Ry N@$%Y1-x8 +b,kzoPb4U-k%FcF/Ac 4y,BϔژE؜p|cz"Y(U8\Ʌ:,*e_HuЦD eI(i粿,-jJFYۻ= ԟ!9,gR41+829ٔnq\u'jlN:Cx9gm]4Ӗ~m$c0w^x<8t8Z=o~s z)k\,ą<hZjqi .BpIR&eȧȵJHɄG͵oA0CQrF}.;)6u %_W(&)ϑ  8"tÕ Sht4`[H:a ҂M-a|_jbK+56bHUʹ˃pit~" zXV=챗TrcW^?2# XR1w!ִ鸤USo*RbBSu/fo]-R76BB1ʡ6/\gF x@V58l%7UoSWw|{c"BvEV0߬oQ.V˶]yC6N yf9 7V{]d576kK;Ra=7?h$0;ק=%]ƈ90n-YO(V@m86qFۅ(?8߿?)cW:գ 6xCchtsfޞTnYqR)k c~zy+^!C!KSoM 2(fOiLT`f%m J;gNH#tu6&Ki/ L z9Vj<鮅cdTb5E-[?,tSyI F+FB)eK ,b$7މeRĠZAZLCQihiIuWq2=` B9(WzݳU?&=s{(\Rjp:9/Be";&Bs9B]|z3װQ `EXxSxQ}+˶sOYq)F?j1Tyɤ1P03ސH˺ zڃvlye`%tDVmaO!Pgg?op?fZ^ Do%bGWG:!>:cYXRU'q0fnxADNE1#Q#-SEт}&Q`PGa/ q2'C8HH  Rhx6 jMbZ kE Z$Rm.~\2OJəZG4q{>ʞ34v5JۀȫOI5W,XzMj;4Erշ`jk兇} PFn 0W#rيCp(̰0SXme|h{2K-K|}" .hѠzlN<&֐EUpnE[]m>f8\ݟFEVFEc?Zp1@/ Ey<^d!X5`ШQh6VĢJb5l@IXF @Z-P"G:risE6ۨ ^VxP.5ov6ZpӮNW1O1o~jevluNNkWRApoE\3z<,kk-Ֆ` VaH1IhҨsܻ{:W,IZNK=fT I/a7I+J-5 g)kJP"I[H,[R/@Ur) s2Aez5ܷ=,H TH@@rJU]ʚ&^fqqHUhW$ n_Տ9)P tChp LW5|`Creߏ)ǻ{k55QNi=/_.Ų7e˟@ρJb^V' Mp;-s B뵩4!k*!^\zbE=OD)KAReqn6R:HƩ+˸H) +Jw/_&4C;j{ $? 7՟GP= pݮaii):>})*9.C$cD-:?]%_eqj66_+#J#}`ZUv %EA3B3Ei)'(bu| HOZH :kx+D<"~aT(k[C? Do됭~8 ,13_M=l,l-,9$Cj!mc_AG5DjUN> 7UCv@U-Gشe}{[ ZZ6!΅XPYr~ _z"GeZ HH&)уG+Zif2:Qc<!M` mld (#[占E>M-&Zzf>`p[][" 8wa {im2> Aˢm SǒT+=}ڠ_Vs~e~q̭ zݡ h`ϸoZ2s]1d%R@S E=a^B-Ε%]`mr?JN/+A9\bPuKMԘS?:>27~CH!#`j=f7\|)C4Q&`p?F%;2Q6xU|$J؎e\bbn&\?҉ czo+6B{|:.F)n/w%O5/WR5Ҿִ>=<鰜(6Y`+~oXΨC #3I1EA!OC{dTgQ-#r6窣T[ YNԚHA!{-ܞoOh66r uZq5p K xkn7vCFsVÍQZ% ;aAP &ש9l1,]F%o匈^>>o牁#l1\Qrvۗo>|eeY)lފl#3F]0P1\n4::r/|(V,&e42AW Bpݲőf/moQFsգ[^bS8F2(;-0Ґo4S7׹ 0Z0IcA;D<=_RAks̕(8L*PMFZvyU>zP)L MSO7 ˔8@Lgi$_yH.p|CUY05Gj?: .⤢ \^֯oSO- OW&\8A|@mcSt5JoW_'ac|Q *^ ӧly{~ l߭koʉ]|p^{"@]Ke]þհcjHASx4^JWϛOQZcXi\v+AA,hJj Rygˍ3f8M^pÀ#S)hLtaܴg%@E*F1Ys \FpT-SJH#Lv}deY)A)ic?crx^E*C*0Ҹ))kn袋}>6.Q֣W%81MG0J a2$RX /Qm4 eR">@xx֍=jKēkY.dXfeIU4YJ;|ZZqQil\)W]N]|mW6\G @USkarցZ'G H3]'l(MrpQX-@-XyU\cU`*m.&$~dcYw 'S!mH$>kss XP]v -ϥii-5Do7j6-)-[jM4H`ֹA')ax"Nl1v8B]?0I [nH(֭VH⛋WbYq#ue @a]՛¬YDm-EF"SA'$f(EkpPI_'ȠڵO V6#i V/|TQ¾ڀ+?ϰhRtzA, (3;62axqo߃u$^#'Tgpj;L@g ˍ[މx;4|Y/G:(͘|ݨLiL6~| s*kA "V&ad()|U)a@("E2W%feH.ݑ8dm}jw`DCdN^8`3l\%Ҹ6@ pmst<:"4c[RJ* pi%@ؙut@CZEP*CH>QƺC88zr :dzx 8~%ayΧ+ё!'}ˍRgy;Y^p@dC1aM#IN#6A\ CZ֤k#_L?%ȸ2nM/.XˁUUc< qͥd+`o%RH6n\h6*E <Q vHbNõ0FU@ONzcXfs:O1nnhna/Pn6 cڔLOC x=ۓX F w3@PD#&ZjGyRrb0< rl=P4q92 3}%cuTm! ehPQxPPLR<$QgϠ3Y #Q! 9..Pf`mXÜ/Ɓ1?ڔfq3h~,wq(BkmJX5JKaY[\[pۤ:7b9^WEt*!8xL'MZ~0EG6ds8.8KQ!wI[ vDR+$Q֮ :t#JkrB i>Fc!@ŋgp%f(S-PPgb:FI[m 4Q?2iua "/ʜ87yaM*mZks Կ* K?>̉Zx*&e"#gx^e P`pHnK#|+bHDvs2g9ǚ- 6"Amc.k>[(+Y|Cx&S3s!fS 歶8IF+EM1m -ZG]V S_=>;f 7YyAF6̆lms~7r9or<%/K x`cOX6t8^ b\s:5pnb?=T'԰VQ;new*LB㭛5Nn0Zh]yq^"rV5-ӎllͻYo;0PXpلlQn-0B9#3f QR@|N0- +VU ˆ&H?A 5%+Gc%JCC!DM&UR4*ՋRIENDB`gift-0.2.0/testdata/dst_contrast_increase.png000066400000000000000000001110701513354670200213470ustar00rootroot00000000000000PNG  IHDRxԅOIDATxLimu9w{nUdͦ)%ZHK ;qb8|ɷ$Hp|0YiR-&=<{5{k`S-skﷆm- Aր梁:5h-A03 >c R.U(5Z!Gm0#P4dcյmS5CDJ;QԨ'W||k{O J&JDd9G P4?C3h(Aق  (F)MP3PTFÖ߻֭7|_~? <=eumP_?j:0nnbE%R;r&Ho'·?wߞ?:L_غy&Szv7_toÇ]L*hRg:oᳵ Qg}ӔtP:)1,K" @ ]it[MVmp G~`^>G==z'ϗl x6+/" FJtjp#HBbL`P@yUtio8؛ v>}r9$iʪ䤊kV!*5ha uFW) dF`Mo~{<_޿vXWk 2aaPC4@"oU]6 Gا|gGc|hFJE.lF1'ONv͛vAEK{?!cd2@-dZ/OW?Ͻ_Sӫ;oi1zӠ BG] io@7kcȂoo"q!kc0كo:ݻXQ Gd~#eʠ^{_O.]yhJ#茹l!DbA0a`8=oU䐭4"c;^BoP3 D-[t{VE|ٜ#Z /Ɛ#2Q0}CV؞~0Y+f"iH^ 2zf楅^ &$̰i֗Fg{? )g8:;KQw؈cfLEitCΓ7^:,xE՝yP Iښn3v8A8mU3;}NgpAGE ˲ܽm&p捃߼~Mӌ; #T)3(u<}pogw<߀B?a\)b*mۭZH+^,a0s01jgL]!k! )I^,PXj{kW=qw0pћ?D Z珖a)|0wg+8`O]Va.=2ilD8s6"%ޏ?Wޞ]>u@t.N=Zu+oݏ_+͖TDâOkq!R޿JAP*6jt0|Mwٿx4=nߪf3ȫg\ytUZg*D 9Js2ZUasm׷,ݍx/M)J\4WnrƓKԩ$* KԌJco†֮1i|Y{_;ON3Wxun4,uǥ1ڣuL4e~DҕyqI 9ztָA3߾=q-, 8R@ֈ!)irt]3 ,°; A+eO߃r1 SЁh] hcr)̙$`SdX6#O~o]ٿ}|sj4qqzիi;?:y InCxr'|?}GG@{2$d0(iiκ1ߺbZZ^yu{z՚j݅J ixKi` O{}7ƕ#}֌`4 a3qxJEζ4L"-`6̦׌(3nYZyhwFY=U;Y3>S~K {T@۔I `;IA0ZH`M[f"%@F1c3Xz*&,PSL!;_}pOQLo\<7pɝAĴނ"%Κ_oFo~Y:]s"}H8u)O3w(9fR iBXn0[uD*gZ+HX^B`M&~&B)@e꺼Jh̶ӣvu:jMVPߥdn`'UbbG"ꦹrpڵW\T?'giQj=u j ʔd}" 6*"eCD1s`.qBCeHʲ`3FELن݇vWob~tkg 棄k\?%[fl[nkmODE쁊HM?f/ɽh- w<9M}yѝw\6Ȍ:M!.uZm- %W# (&.i'g\FާSXjkHaC]pQyX8[[ǣp8)#ɶEjex2%KI* ItvmgS{?xtޮLOs2NU{*S% 03W( TrŘbJmp1 ԅwG"bQNYIצf"ŪXSr-|r+O.?9ݸu!:[ٜ$LrW^uF.<}{>{d$ B)0#fbH1ǔHCc<+//yM]XRۭ3/ :4IAj,鳜L$شpz#ۈ.b IEP:Mu`nݸ:oֺ[GU=6#2*AGh)ifTMM}_,~O_x3&Q0;#K&JYUHBIM p;D)k[T3S[g=\t\f Ϩ<{z`6ۿ\-PZm(:3id5zcIuu _|yti$ E35DY#0!ŠSJh楠TEcR~w&va\RHMq݅I'gK][6KYuqdq Q\`ĎΩX !tzeQ ?_jcqC4 lJ ƙB%{S<;8e8vNg#ĭ+㽛OHX@3rHT@E%<0Rd+(9Wx=`NYDX.ZwMegƃD0ag-E Nl.']|tz!n1oc r }56օ `7GJ6s3cTVy8m2˒$,w u!xS;z`e.K!MJmLK(MJ' }iMaY pdOMelؤøeRb.$EVM}e3U ͽo~ i]SI:{akn4Mv^۽v[Д>ϧ4 `O2{P%C)uHZ(.RBQkɚ0V֌4͢1غ9$Q81bJJ)IuzӃUlIO"΁5(ҽ*|.d2[Yʝ[J%,4ӗ3eJ N SR59ȉy=8ɴA!7D  T5PyëF𙺗WQ2[RJV;kڻ{ﬥ\Pl<_}zh#Ss@G̢ J ~l"uv>Vu5uoC1OcQ(6ʼIIE$6ȈO@N@}% "sOh++_7W5lh18 h8ȡRfoYۯ> 5;U;3{l$?Uݜ ً>ɇݞ Y^OIj,DzcTH 5]JXٹ~F:EI)fZ1qN`2 )X^::zvyKwDcd&|am嚌y7U엢R@%#l1YPX߭n31i[!A9SU` ?$E2Qf$@3تD,"jkb]~hgTVP,EyHUD %C&JC_.tçKvmMOM 8e^>xҝӟ:_Z!ANl#RRU.H`0Dgxt;f%IRyX6hNc" Ǻ0#o7Fa6(ͬZAU3t!i+7 +/,CA)cefAC:c4UmVH) Qg63MG笃 '&& ZgH (HN]2°Eݠv cjoX_9^J8F Vza֣?uNE3d}WovOWgQ7㴀)Nv nJ]]>{xp}BU|XSg!HPNؽ8yBm x*h,bd9%]$2ff~ü-#GnH)Hbo.6|[7n|O=3Y ZJ1rggߠcyb@1B}Y[ E8(WS]A\Yct"D įT)O 5D`8(-{,J5Ѹ2MÉ&a竺 4 BKHk՛\gC*Db:j7ozktt=[+(Wmv-aPOϗ/4Zn\~?>aؐNn*(؄twݙ̦XKksG]L*okSdA1=dK(x%1R&(6Irg_,?!eκOζUݷXR(vFC]T_R3Gfֶf\7#7K([ Q@huZa̜J(kbX *>fT-SHRQ#If+O^TcҫdSJt`dKs,8}&TwF_WƯ`.8fXA:ld;X|Kfk_c\~IS>2% !k*].Ç.l6F)C%D*15[AmKtWP-i͊a3g61nE:;*W Yv>BB8=~ዏZS ,ȃY e.P^Yh~#]lW)VYĚ03>1U9JX)Je*hIJ_CFPVv1kkqʠrQhTocetR )]4t''?8(RU~ʹP.VzGZe 'hgGevo_Ex;eȅtWw9(QBgcRnъRp² q.Q2RP,S+丗 ]n6%G^`m>?ׯ~/9ؼtEU+j,jv.bVHBq!+$NDը##dR(dPT43,&طdπNahhrY_YaDRC3nvŖn6zZS}`ri<_ %fDSa7|)TRtڅaӮ߼0?m7=jF *]-1R®$q\UC4,f6;4t]np3lmr-AbEU\bUu1MN،_Z4ڜ=IX/Д/}BR ./dS=Wd,KW]/(ˠ:i#*BJbSf^qJ% *-N5+X!I?Тd`/w/K}ҒyW(g~TQJ|pi04x8cR]CY])ɰ-ɂ5^_O3\C ).~rK|5}`ʆ,4CJI|Jlrbscb$ U`LL˗.Mf;`9" , ?cr)v[*.X婲z7vSoIo(;he J2{Bde,y}U&J1IO"H2h߉YH Y$AGg2򾳎@++Eyh딩y5"5t`E;HT1pu`o*HV*zxN-遚?㹆 8w]PcTg;KQD()NlF rVPO'\v3]2BP3 '"FsJ{o^hG4]Jw?Z88(;A,KVFAڠ6!u M۝٪}zWC/dTH&bJtި:)n! *bRxTIZL \q wf,hE ImT 9۴4C fq"C*Z6^EHldе앑^d-dM ZnQƷٽ ojXGZJs8s1ՒaMT!c5}؆{yM+$7h-!+r6 ;um :x*j+6?!tHraY).2:T2W~Td_2&&k3L鞐JR ,\.27؜/W7&,7rgﵺ֋z!c@P@cqJs[7h(PI*?$MYMJ)*ŮTKlm}H1ƔR ))SW2΃_[ů?t%AlPidGR6 H1İ  <6t]Ll.RʥY"e9X ZX#8vb~FrPzLF'hlV|[NVi{X[)׏~^D^#G6 5Vˆ2ɌC?4".b|FrE.l6 wF&wGaڲl0)+l92]׮{kXLVW_[??yz8Yѕo(f=Nό])ѕuLl%a(9B9:߲MlDxps#K,SMmX`'w~"j!`ƛ?2Ώt|TňOC]M=tJ \0ϗ ۅ(D]P PXiuC/k[dL؉^,ʪO k#:OvzaIIO$i}6,KQ~cZ^U%GzqbEY`fϤ,HSHB *ct/bxY}T6cgj\z^B(c= LvOO<<+_HfRM znݵMF>x (VTD'Y1dfy/b:?>>}FqYUMU|UIURb/<%B ĬX&H2d@f Hd*>?`pBb8G[Y aܓL g(&EjAe^E`bsH[A߽嵒98CŀBP X7]FɌTVEEQd{}=7bz9zEgr'~ϧVoSN2o4D9.WOœr`<( ϝI!\J9js0nqv'w,B#1lkҵ~U a;[ -m^ݹEVnN$22!"JoqWU$Xˑ)'5.Ǝ޳4f=M4>ؿ|W QB>( sbすoʉ豈ܜ -gQG>$G JĄd h)Ra.?e{+y"2sf^ih&M=pfpAR"Æ>"G7B{jխ%lT)۴XL_e;s>:2zx;!CP0tf׮:+߼t1H<ft!ui%!9+~T*Ο1).C-h*!xD'~1f.v V.Un/V}]]F9+o 霙2DcdĠidUַ<E ޘJު~F7zķO–A\aJ! L /eL-{bSlCuy/RuErN͍vnծ%9aq9'.:V"9 RϜ"on\mmmϮN_<8z .ÕWLvtvgdgෆ8@U.ǜ2[E"R" ̙;P!f9ڀu:^j3jmF@W%3Uc}Ou6Mv0IM:(=j8}AB6])L73/e(r3X={O;&`ظ(ZH_|f [z |f;6VVIz\|1Ĝ4GUW_PV,pI]Hq ]up:kj+mokLCUYavv>Ӈ(gyQd&E*or'`S{ 7m \5ggJ o^xS羚2p@Tr` JؠWrX*_T$:{+F$-#G=__PJSU=aRdo5&HIDRLJP?:44Iƒv^2v s9PZ =v]t7kqvYJ;‹O|cuڤd6y|彫[WB]V DfY$*D*kƟS|=P9_w_+tf۳V3AԮJLtRLz޲3H9(} Ǝ(19XO5)8cMNSZ>lm>g\ɱMGpq^J3Ippȁl WҠ. BPNSqE`9^KlEG}-ER%zg)]~*_:?/|ʗr:EyzJ"LeB,jw^:ʜY1c!R '/6WCJ JGA ulٞZR!YIwO~w~I¥!r`+nώgwZ8A4`GI!BȋrWv\m$Q1 `r"׾8*kg$H 㑸rѦ184R}n:Găm"^GM@pΆMa>f.JO]icç&J޺p658('U!>L{$-1o:wiݝ}Ï`7:3dJNq4%#׃\fŢpZ*9 )&-dE딤m}Wkc)l8Z ʛʼn:?{εhI,# qV]PyN]K}b?IjIL0x@R2'LV0L$ ǥ*ɔ~8[CO|JO専 Ą$/r@B<.]/pi.gԫn\e5vaRGȑ#tͦk3ڭWCrɞfzR71G)a9$%E bjm6]T=msԆ"n (ѰNQvrFr "e^iӘbK"ZJ+"bVĘc j*$]Efg zHqzov aisVȁAg#G 9f~|3#~D2 V]Xk QsH5 :"l6U(/4уeXo)ط3t u0h릤qHS,ppu会m?9Zqr9KDw:̺yEkN3 IC/QAgG 1Qd5[X#1h.QK?;Φ+M{>o_ouK(`O*jiq:z̑U&*AnDquq yF[E@ C(K~ P5Uvѻ0`-9I5Ūc։De iQRNBľ[О9HET Qo 1i$PHY_"PVpY9,Ch/a5fy¨YuYiCQԼ8dzJ)+PުD~KfK|&LHhf.w64JoS h0~XdIyw*o cgkBLj]%¼OEtv6mmJ).QcR$? '*ľR:ʪhJ;l0JOa5h+^hlXOɇf<h܇67[Ea %^R)1B~%BXKFKV€z!pG _He$/RxK_1JSbÿBd?hp}eyhw6\ڍ]89{y|9|;zT4"*oˣǃf{ڕuXtQ1x9p}a5V ;~gGSPf_0RJh؍x7tOQܴjkϦ1Q gEƉRn89rBq% Bh$?/Q_ `sl;߁}0 ^vpW7>G}>f߉/ud<!mYP 3}&U@Q /P̴JT}BAu4 ,H#&J,lAKi|1'?91$(RI(jg9();X*T9QRvXRŒXM4%&-@Ҝvu~9{X{n@Txs^[k}Pb7Fl0S\>B3Idϟ}◶']{݋$V)|1P5P%׽ 2VT۶ۚ4vNwɛcW-׾q-Rf>;v{J܉BV6[`J|x}9L5xp䫿K/V=Q=3 [kongkk+[۷pXS+u;1W> s'v^#4 7^ (ոܿu[o:| {Lo ,E)kv?~˿s=eZfoaE>ךGS%19Z9JT;)^./>o{%Euv9$~uYAo~ ޳/^ xp#ET‡'ùŽ{ORT)ieViFGbѦEJ7WwXăG>"}E>wNnA||VW'ɹ9!%ʸw .r$$l eXCk_[_zh#7kl)-W׾['[,/S+=^X5`R+u[нd񹏾v; 08:M]΁zw$  brIA9DbՓ9i WB9|ZEe-#ʟa'3HWSOK9|W`GSHQ'V*c庪(ZӁmsGLR"ITB.THQpa@P߸"B၃J"y笝i9 n]`nL';\ANΑ劖}ޏ?epyz﷿A[Io)TZZ),;=k[kg~wVqF`Fcօ@EНO{W I\<<ݺ+,w8) +(T3R~T^g? 39M?_}t2RY] Bt>GGCD}y}މ%4 U!bZ(5mA6GWg+sXC%cXJN^*l !o|H<n}{zYmw.}[" no͋o k_0;7^yK_|xpKsM*j Tk2F̱5V)-֩'?O['na:[ۜ>>P*F^HHct9(\%LTo}xeFfDeEn} 7Am%Ͽ^G'S/"|S-n.OQ(01c>!G eN;n EF <|c1OhN2Ą!x1Q} wCXI(`;_7+pĝtf]u O 6Meuw QR c\x9Jhǫ>߼m9w>wx~%D`RsP Lz˕rf&+)n7wj>7۟߸6ÑUv̹m]ɳb7Q/sc|MS'Rj'0 EYjɳ{箂寕]4 .l/e=whb.q w ='YxP6"M:%qq~忇7yToor;r}Bt._hp;&҇KG^>@1JG,O&v΢rײh4qLm@T%~rC;7~cNݍ{ӣ*K17 Uwpwa9o|K?p%l5ɓ}]<*/n.^=0D52MvϞ{fm_/I2~NAkO܁[JuF?IXc .{?ʬId4j[Vm7]G'숕xx28Q/,8λsk0>BGӊU{bDΗ\a* Ɣx`IlPwvtƪFH!q.@c]ցM <x?U2cK#i@G|Փ:zp|KkC^G>ϼ9C~)Vs}/Gss)AZDHR%J]l V+-HUjnTF={KN}ٺjC@\3$( O/@ #md]Ӟ n jNb=mX!87Tx|*:\r8V9?:G?8ROelJ$2Px#! }.7Y \8YE)wRUb\=A y }]yC8S !k؁3An^unx?ٛ& #_{LJ~^1mB ɟY />-P<7by wVpAXPdMM%kPu(R{3{rƁ?e)wī."NdŽvaWR^ϰ2RoYi֝ۙ˷n߻hgZ9|>2|{?ܵd8:ZeatGh l,*Z54& J-ܕQxsA0TZX؊-;6G^oJ-1pRgڗ6 ;P}qbQgn] Fxm;W5voԵ/G?z Y7{Xx:!Jx9!GU4ٚ*yt;[V[p{*|-K ہut<9<:|DxkF ~x~[!<\!bS%UQCmmi*bZzF`rSX@!r9sIdЂ|.E6o]3{7.xk[/w>u60W5\Gg/%r5- 4+geU34 Lj5s ܙI?bdbC9GVA)QTe)|ќ \!bL譂fҒ/WΏGW^Q<+zjq{ =g&&z|!^63Pj CP@Igr#L8׀vEUz[޻04,1BnRse~huƿ-'<_l\7L%alZ+;]z{?@ Z-u~bw/laPÇ>tw8eX:8DƶJivV[I6(4,1) c *ɢ\@W9R$(,j>>A%#'6 NRrLZ*6!0F`Ǩ]X͊e9띻v8` = o. /u`v o8b?M9-^I\d(%xX$"SJW<L4(Rd0_ sn 9&>L׋|Wԋ9.!ky;( FW4% 8w p5 _6^Z"_?#8[_a5uX?r"J^bg!FY1PS`wL, 1Gr+L)`-gխe ~ΩolS0JbEiB1J!ӌ1JkSr>cO:է[CtgI܊rn~ ;߄wk_7R6d_5'T56< Ddw@pv5r]У:EDAf J,IˑIH"Q E7D?Fs$i^5Ov9 O`m<O۵FIgT:B2i#W!])eF13r,Q|R$沄蘤 ^ya.+@VB]Y?_Ågoěb-%"#}Vl^IYe@hE"c\KƋ(LUTZֶj#TeT2'ϓr 4BN݊S"L֪L`pYW4``;Ltg ;xM[a S)rjqJ}"|y6E #Q3-taj2U%Y7'e؅ Vן!!K/1Ny-XX$C ~nn|̵!%ekD-s2F__+p4`{@* y}$$&\J>{AS"o5p̃0R.)luY J ZHCZ+^UD 5xfUlǂ?DDʏuU3^@*`j dz!&@A$fe¹~olߝ"?|s8v6Oza D~$H w q=;;w)XXAz/9P nEȪ225:R΄Cl,/Zұ8HxURgMfE1lN.(zza!zUPjE,(o%)7~ ۚ;Bٝ('c6JY5n[v#*P 8kj n4B|WM:v 2,Q,a x\B4pqVFWF<~d(?:PxŲVd [`̕]ǟF T7p}^ewV!Շ?هyMU~ R*tw~߰=moGn OUgzUE^q{r=ͤ-qЪDL )awE65Q z\ƕh^} * ,Y+rt3N cκ`Z=^s'MK^eWoI+u)'+jq{_BTJ1Q 7c)Dnl0c5FlK*HŽC@H[^1=,A%U5dXD o0J6tǮ7\/8 ;+ۣm0ߤajfPJ)(M:5eO9L5 JmSQd ?Q@Չ[hqtsoݺ}pt.7Vmng-̺16f|gTYZmv~C]zGΗ}oixO T@Ƭ@F1:'ݔo BCLDU{CV,wZbNjz|Bɪ]s @X2bjeUk/3Vtn)nL?Jxn2.Óµ'߽I ϣP3k+<5 `~>#]+gCԨ3Q)ذ< lrNIW|j>'nqxs7_ nR V)CLMpJ kkm'|wl~GGi7;GD>hjb4`~M`HAf2J1SfwPq9$Vى VQQR:sy;1eE&R2gHsT (?ݤAlI}$y1QG25_w}^ӀW[jJM4"+V ;)eGxʍZSE"*@z^q-qA~9Pr#jAr#4 M8$Z|EU9dɻL2YvJɹqA,4Ŧӝ Öj}dJ $rP)Es s<꼤,L QTr@|53)Fr%VVt.zxQu(Gկʖ{X9G9U+>r[s⓱8|(q4Qxb+ZDk1U%kM#=4PG w#k]($=sIZ a@H! 4sJ);J)IX721eupCnss G]d*8eM1vaJ@ SZrˁ Utљ8$SMk܈)95$θ ,`Z{ J`?(#<ܱƂmC 0kgw/w%t! a=q^,bq=Nx=3 ilBlڦwˮ5 FQGoıܺʐ#RF(l&AeJzfw./P*!1 f) #1):J(!N2A /Ђ'R6:bͥWH)g-v(`sNyt(0JTY|P`ffZ7l&RQ&C%35ROzAYXџfgdCL Zulo5sѯ_n\''jy2Cߓ c.v{3{{33Ke(@~tk NT(hJ"ySF hrL Dbj#[R\+ uE'Lj f,٥j;]eĤ#") L5')KofM2@eTQ $~=\`Bmu6B.t&D6yڔ5ZPeě# v`1WMg;s_{rx]FJNuq=W ̤<&)bܞ+P.+e<8 "$)gLTߜ vXA }$3 !UB(2kѫjOUHSyK)$bfLAS^j-)NPP2:>#.N T E)2^exw/Вo`bY j|n%Swy3z(FxeKfM䣖kaVSrQjEK&> AP麭tt|p:>YhF1n>_*Fj ?<>:?]Dc\pp})Z')ٗbG%niS]mc$ #ՔGkPVW%J"* ʋ[K2,@I<ɲ'(b I~[%;|;B"d*qMJv8%KwYbX$(Wv (@J*%trӾȜr4K0U:F:Cs^6a\Tv^6h薋d}Zc?p'ttjǼ׬tfl&J1D8u'Te"E.N@E2$}$:U'{LXJ m$P9x9 .V&M,: k7) G}CH)#bT /j6ūSRd4z,r~@[8|v\#9 5aGTu͌JkCn[my9 Ã08 M=>%k$YIv+|[ŒZhe*.X 3J(76 هdJR`-q~R.*[MīJ)):~բu&Fr f&kV7JV`AƚV(1d3RKPG51$id8xl>X|kVxdr%OI*iKK>W@yd >bO|4.OIHr*y2r=b)R5VHYlVsBAJG's.H(/QSֺR)acbJ3Eh@SX9y6ʀVVhqlO9%:@YLNy\R]l4k0K)KikʇzQN M#ː|Dܴ;N5/RZPe* ]RyY ϰqpiꅈA]h&)PIQ=g#"ZuZYj=) ?ZӠW Q{)sMSwJZ1/%Dhhus%aA*]r Ge 1 dLڂVeZ(آ9*w"ftDQxtXq()gAENLh+וTPuk`P5XsIfryjbB4eM$<ۜV+4(84\}"Waf"Ȋ Z>a/jb${n4, {fqE45!YB{m=%Hu8Nh@yN/% S`QڲϹ>dHOGF";S'%B9dDݹ*PT2zT+ @MPfm>_0\UR1H>FiRRRPU{#FXUL<΅&c :f1 &G]eiװQNw"kif[p)xugRR42B# HF8:ZղX1эNxD0WZJ!Rj{ko *[$6JqYxWUf& :uCmK1O [wTI& 2 RBk)JL*ux&=-c9'_2TڔE3ij?ڮÝ;`xv7mܾBhyP-:`ßOjc\)J䗘`. _ ˷ @ ݥ>ra0`,/xD<*ヘsiD9(E5*ߥN%{#Eໍe1` ( UPC 1IU(jUBixJBۓ]dY&RR"yFb*HD*I1B S%k \o_0R$R(!4| ȫ3SҴ 4L 7~~ łι-W=F0~Z'j ,іhL<[,, r{_[Kw~Fv /7jYrJ<%,)&jHءNj((+uVKiJʥi~4Q>&4\Vnt| ccK\Dɏ>OL HWKdz]ᥣqk_Gb٪)ꐂu_Niq|`|;@9xJU@a +j>jV`i) igєKbiMJeZi5Z@nf$ X`d R3 $y`@z&leמCԱ,RC1CJrRc*~$&fIh"OظOxʧT_ʂbr1ChVcc)ԕ#`Jɣ[hP @л~^`tq;>|͑ӯiCBWo{\+7frIaKBi; 5<` k4,$jƴ;kEkesH!l] s$Iq͏꙱1DKv۝UwGV9UhEqq4|c @S5ifO !͋bp/sd2NIDAT;Ww(aL6o0Zmn* О13Qt菪q"f3?EtٽZm6:%}YoJk8N{'1eR>W#x RHu 3DƗ. $::CcE8I\>]M`&vW8Q/!B*}z2hRa-FR{W;$Vu^~*kp9vl1Lda8RP/j>afc-d)D>1ɳu ͣZ Q?rpgڂl@SʺV1~Au~F~/?-Mƙ̺9+jT5^ᦷ@(S^e%īssC!&Kpq)G`^0?4J^i-Q" l>"FxA99*^]ͪH7=:ŬԺY)5ksnE6NF+e6(d\␐u٘6ZXk{w2Q(*[8h(+h),cwc7|sF2nc)^Pψ'mh|QfFK^PxF(6Pp7N_-)J%JB) 3:v7AbU=L`IN4ـ56m\+V D5 ,N;sS:/6$l'qDX 8$840Q+Y%olSKAIIg`p8Uk̹ UdHnmnohf4szv9ulFo;+s +[s|o8.}Yݼ6SZizz=&K Vʓ%oPX4B`8R!ٕҠ26njӆ{SѹJޢCحVJ{-mJE=gS`(tW/iBǨ^z0Q:Wci}^9lSb$Lk%6q AlQT2|^](>J$c=!OR9쫜euBJi?F?oݿES]"C m=,2T;脇#E#D܇ui?2-!E9B4^Q\0 RSIM*Je[Ky-.UR@!p;`H:rm d0Ĥu)vv;:JMx)VѤ%y%&G k/Öվ~[e+76qEa~+]$ڗ4?o ܖ@7eIM8.1D4&z*=Y3bN j#-\ʳiFet-^k]\jͥx лIv XV9ӬhɀSTj0ZAdJf^1TaKPO'"H[k~A>d)۷#|˝9+z,[>DJ~ = @*C v&!Da6#zHA{75A!y]*>_\GWT3tZuGʺQR+$q $h8)d(/Q.X+˜ӛx “AM{S5xcY<پen,?owץ nǂjGYRH ;qJ0bLhLԛ!bpzd3@^݋>ʐDF"E #\ښA5l۶r5ol^r`mkPLBWfLt]!HhsP+݂zB9y};E8)% $FUP?]?>{ -} {i@w /_HBn#9l oW׶ Ϟ| ǓAbr ;-aPo n2\s`sj,DsC։լVD J3,kιռ\vuw4~ԏ7?C5ť%(qB,-A ȏbB;A]F;T5dY׳-v9SoyZy'x:ezc>HBD/n/rt[+gDO^Y9ǶID4J*BT}t$]&hbxc6v@ʍHzYL}YA2I||RY^_^[\ʆ.H 59v oi@pqk@(wE 􀭛jU3č@3hNfnQ@MXXm`Fc9&٫e/uݶ5}˫W(֊ vx{,jL|(P3N WLGѿGv]b^*!9 V:6yOxWzlϫ?2'WOP'"/wǯwd_ň֏]aADymB-y.Pۏ&`]Vh`*ӰjZٺ1 \% B E=y9@'00i5]z_mK͵b;Xȧjt ZiaE3{#aAOT"'j@`$^Uz]KĀfFfThܷw,`ǏT~x_B ї//AK>9 b꧝dpU?0w fr7uPNt߾9ys{OXpG4Ve9 epM>Tmfe̙ց[e{wwU7-:+mXe+G5bP&j) ^&"/ SLi9G,Vf`hc̣B1h}CQ"kbͭS<@ /?8u9 !"qa7(!BZ)-X`#*d! D xB*h"Ppbs].8z7K_s߻qW?TiLc/ܹ'~sS7l.AhZ 4^|%o?ЅC\}bS?S/"0׃a QLe2̴jJ˴%@U5Gpw @ssO=g w߹Uq8 5c H͡@ %Rb{pL f43FV #Ea-+Đ`HL LiΧߟ\}զcpZN9@H*G=D>(9)ĊPCgMXa#** DA-g 3M8 ;=^_WB+/?'~?ޙWKO".x>>ֻoAYl3WVnI}g>3 xƒZ:Uwn\/̓'w`?NB۽E WQ3&6vLXU.!@)0}Vn+ 0pb>Az0BZPSSŅ3 B1kQ:Ϲ%@&RiB@&i@`2Q<&8!9J^W?xï|WZgZI"hS!RpM (XI5 h H%P fdC4ME҈λ/qYܩʥ|kz:¾uݮ,|*lLv%ӁAxGS|Gp/=?)/7K?c+t G[o\oZ{_p2,8'Dtn[pMӌFn"sgX^:p=~iK^}iwb`b#28ߩ>tco~u\tZ&Wt\ 0tPM:cDA{T#2S5dfY$>DDfqɓp)cSQtzʐ27!RD+T^I6>BM%s M&*QZˊ-S AFJd GXm^oЙshg>sWݹգ8pixc-{o YXcs"Nw.n=y? :%wG~_OO>n\ K(@lnܝޞ>b?`-{=VBPj֐VV-us>|t:T7",2,P:hX0@ \4Db)FNJBVǠzx]}ՂS' W&"@PhH&TX@ xPHR# dJ4(lL46t Ho' heM[>$1ԗycڟ/omyc3`=Vѫ1oAvE'+7yZ}2/\Eq3*iAR+yԑcǏS;~BF0ʾ奥B=>ćN>;p5yObab2K6Od5d4p~-n2rKmlڭ u^;}c`)δ?^T82~`9d9i 31H3 b:cv:+G}8n\{ˋ=ۊr8_P;h  BKE"GBI¡4h.QFGdNJ慀RK_Ry+1њlaLY{X'&ei"S?r_Y"CfBU{R.в,`k?xo]Ͼ p/'$L;O<'7C-YA "#=9'Nݢۍ'?zݭ=?ߝo8<ށX9~pN{[׮^ڥ{Cu4olvt~:xmkѰ`}w;_Vƾ)]:{u[inIJbA]@o JDT0BRZ|3rnu˧^CkW^-'rAQE2ЄP DI# ։6aAH{ 3-"71 Hf5\9ȰU_R#TXCtW/_[cO>ҫGoph({'OּKz*b >(߂o~'҅pydmsMyjUP jnjGQRTf2T#7ػzZjSGxV*AMwvk:g[:sܩέ[{}Aׇ7:_ݽ3~[t37jXtm 80pZ޺?h+ה}LYNzj8lFSj2޸ͷ޸}?Oly8R)r $J%HI\@DPErSt?tO{/~韼sG`9Т }1Fr PrI$W{/!R$H km2jM]]#1WYm(äF)V:rAk`PX6XG^?ԥo޽9*r̓]ѝC1RfUEmw,o/\צoo6*|j:d2BI5&(cˡqeֻ;G56omO8;֬nL Q]NYÐiJpUEY)q H#@6*BBʪ&ecJDa$c2c 2],SJMIk&UJ/ꝫׯ->Wn]uݔQ<+- Kxx1xߗr +6!׈=S4J I0&9&@<(JR2h9nBp,uҼT kÍz,w@Ȼ0.;{ t`16q- dz{xاX, F{GO: 9S Le0FI( = )JiF*FC?ѷd0j:CDb|c`)#&Q@\U.4Z:D3F(:$+ @`8f֚4k4eά2-e.26NABSPJ&08۸A~N=M\QŅCIZH ͓l=Yս7HWXe.zD!P j"!8 )E==fź I>WZ*a=t*GfhYEG(6"UpfӅc&SM*z3p>ձZSLt\~ _?~=kGm)@hXABuV2ݻo~wzw/:@CĦ$q !T4MđG*c%ćhH\@)a6mfNjkɶٌ#JSENx$aLνks|k7nFRqj|bن Q!p!Lvݭ-:ŤfE/-Be0`Gԗ7~3ԥp!G |FلZ]w۟b;?0λ9sL5c#y/3ƌ]@ŻHe E)b@k& Mp#cP:3EauQmeYf.+t@q>kR|0A$#)5Z)7 KgϜ:9|G>t.{,ɣ' -]W7LgO̮0I.4,iv@dyTiA8@Ԭ溭^oiah[|cxŁBnU P ZЌCc*|#t/Xz4QUi[usֽ`cKgZ}Ŏj%RS(Gg/zB  Uظ/Uc_z3|a!EhANL6.Insa5cX>t}bv>ýޚBlz0&ЃJCHTIBޒԤsoܬvm2vӚ7]%e.;wvz'?[o^ߡ+apOq&1e'򃶽EƔu?Oލw|ڸ/;%Q)6`$Ph¾)86ZkV&騹>k_O\T`Z֡^"H`hq;zU5U Vu*pc3{Tugk_[6̄DOZ'x6) I)tIRP~c7qǔ))HЈӴ:H}d#G"v16 e6A(Ԙ S^ɍMp>4B>F1EfT Rg?#&1(% FnZ:yͫK/W{wm`ܞ߱G&BXٟe&s UҼ?cO}{;tݛƶL|T!6M!i䗁9HGs ׺ nu+o}Ҫbd20(ZJf:h1mM[3NkmR~׸׵Hćr~`=[G~` ~굋߸3K?T FJ4i!"PR:m/Dsuw^6VWOYBBDtQBiԳ-S^{WyJ/AS11m4fLZ@EgfNrG'΍Q w[Ea'c ^d^Qily`D8T8ww۫n¿՝wËo-[oprSYo4 <8ƅ+ ~u^={hCsν+߿xN sbqV^؜|i|Bw/~Mz}FLr8l1WZ&eGsEv|HhYD62ڸFʺC⨜餑0y;FΞx򡭛GUۯwo?_KvGL `d!Dgͧ9.z sH9dc=WG[\,Ԃ!R+IxDXyH2,Sz(ݬbE!(ΗAt2m[63Ue-3m".DAf@f nte1"E`ٶz>wħ3;}]AIDI {; wv޻Js{uup\Tn2A2DI3ʪܨTDnu$n4Z頚b)n4QiRŒ%Vg-د*l\gF05ӏ;vhr{cuo\m3}Gt@H4)̘#Bu~:rMŽ%Eu[^*Tl9F&;S,^Ikg%(+Os$1bV&LSy $nZ׾έR[[36gЊ 9R*90+6%`f;$ ĤBbQP'H Mn4;ij¹[۷.a$,,ĴJxGӝI{Zrp_^o߉70bA&D( d tRM+y\m;wF#0 aklJ s v֤ޫVw/eoqrUډFnDi|6{r$::cfp{~|~0**@U56x֟tȀdG@$$X_;͋vw@Sw%V>jL]S{פ $j&`CIPԆɧyNF^Ojg6Ytmgv- 1xtA,ggɘ*/$!YAR`"1FR /(*tSb޾ʍATdfvwy:Fq%ݲ ;&cNj`>gb9'uȳ߹?YV|ۖakkgL:[sV3WU㢯g)8$uwjJmy}K8srɫ*_9!=+gP)$)&LdHwvKes^s\M]N:4.&)A1F )0(IHGIA]<% *lavk2z !zAgG#8Wdֶ)B3@IO,/Bh ݫ>v\7I)IyPI.8k#5AJW|nPX۞ׅ-MG.Tv.kjJ@ u,i|6FwjZ-ؿ|^ҥ['|{(U9 CJ:F=S5j5*i-77?Caݻn% Ĕ6K52iY-¼5*Ќ͍@eO hjHr ȉ8Fh LXKb͈C%4GD$ #y+\XFѶZ1Z";Z2"Eb5Th jjfHRVN,GYFpZ8slnL|ٹI6:2:PgK 2+_C0E9yr+Ow;M2 a܌BTsTsWg'Р2JN<+1Qulq3-h@wܩ;ߺB"'5U؎Jpg7Oz8ozv^fGV(vU$F<[uV,}pƛo|+O|>ۢPEhfI4)X$#HljW~&#.M,34,AqfqާN2#2=}Ԛg"@.-CdadqÝJnQ<i"OTQbҩ0h&ZA"9!xL0Hq U5%p4&'b5DY_|I8PB E|҈T"<{O_gHSGF_sg^GlZB`if(($\Vf BX9|&zMѣJwwIey/}[q]AS7MqΛ=_lʕuD)+eZ5l63K\U/w.ͅNVءCG.DZ!2:RCѢ(.ϋ2B㲴r\E@Jyv7hFQVdrvoGŽ) @fc¬+,B"o|bM"+Yo!%/R c>hOM:f\CHȀNC.I @!dO\8}⡻ž|rOP`X Մվ{L79Fks? ).zRW-RjZ;ݹ.3 &&M'!qFK0a(:V)$[16ju!&R2*5*AKc##*WcibBnY P5up`iV`@A ^0%B&FK%5a;/wJ$b" hVq5DHeB4Nf 5ȨqB*.BA{ ;gG-tw\5ܣ#!h)+a*4uc2F!̈́ZYk՜6Be ێR6,z,Gq>iAYGN2Nxcv7k  fGJQ\ ^|#jB4yFą-2}uhƐ*oVEu*zY\=>i&t[7;מ8oiZ f;G{өG|7.|˒JՊQ τ0<Tظ /<#ÇV[p E` *#[ee 2mpB}J-UKy6E`4cH%#F*HfSDe~ۂGFì<WM]W.M{ۚ]kOr蜃V FA 5.A43 gl3 "xlSB!ъ:s/nx7>USR^{9_{[[>ةGc(ƸKLzOVz"NX !y gbעiv> Uc'N-(G il&|Z:} `T%U'vwC\u7wCB[whl SVzY)*Z$.9~7ؽ[Nyڪ;p'uxZ=fRz=8J`ڂCy-:$IDL֐$扬 z!G,c,X8!+ۇZX>\l)5aҠ+t%` @*'V^f;^k # H1B;pz}m N,SL"]  #`|Y =:q?θ/0g #hĩ١ >xv|뱚ֹ½0 6.;7;w|C1$ˋQA橙V-XZZOd&dZAmbQo}o{bC0˫ 2]zÙÒJZBXJk!= Cu 6uT,d"9,C$* &9=`BLpʨ$1yYk  )x(BBe=a2㈋T߇D-@z‘p.,B!\ բ+cp9.fH<}aD3*1H4OqF<8=w{c$‰C77޲}x2Gz~n kgswdyF~y`Dj]żR֓ZMkpkPG퉉f`tUU)Lxs$զZKk}?/|Nx~92F +UU6 =ߜo&mxRnU! gQ 3{_0֒ i~'׮ҽ~־cg M_騻(!z"ƝKeJ(3T*: ph_4GP,c2Kd F4Ƭ  H\h1x;LuF;=MhfaSSMUN}r3m^υx cLƘavϩy}蚨O7 .'Ʀt)",pS,5$ lʙ6!:DNOb:cx!dqxaDģ <6Bj븪lY{SwnjsvJ=w9ձ"QX[_^{ mRye5ìR/$k{kޚA82?}8}8W_n|޲wfJLPq4U8 [)PyD?K2`(II\1`0Xzߙ]Hi%f'=+W/lUn.\U "r笗onoܠ6 RT  i8\5r20(*km$NW?zDKBy{ Q=4[K}~8~YO|n#( ƍOos/ <؂$7_|>;cl6ZW %5;`_"AθA=9UHI-E=sƗ!T8 Ħ'ۄH(($lޛFByuՙ E {<§DFK ]owJ .=[*ӝK3p| Jۢ0K c8N^(-eʙ`l܌`212JҔPuZK,ffڹLC f8s=ƠufB"KRnX)#R 5$a#_=!:W_ ׸`8:oǃ0'Gs9/E>_W/'1o+/.vv&ذRըЪ4U[S7NҢpDh{"Cy`h~tK "<%E4;݃ hgUqf""e~+zL6~]?m תtxKӉIjbX)A48$W]:B?aQНލ$i4nƛ7vnH]Z[=s Pm0&S.) P>rJN3uY~ʄСLmB[,MDGrB8`UaEGƵ۬}cq@F8gqW:qi|7>3 Noヿѝg l)v} zC5§BCNhRoLG[&Գ" I@)43IhA!֒!L3O|mo|ŎP{}:]^<^g/>XesG?P];PVRG?rKV0Rԁde9RqFXl՚J"!Ѫ_3<{6FhSUh&e%PS]W=V%9.+jouGX?|'n{p0w'mh "E J{~чfo,+Vw6'vf-{oȉI^i#2<W""iH9C"4N{jqSgvv1P fUײ9j x{!`p$4͈Z$8e#W6^_K_zHI1y=~a0_p$gX^tu+wytVWZ!Q:0tu )KT}g8I60^42 D)#>P0m}h8{/~9\[h5JJluZ9UqjEʼ); L]7X\_h1:6^m㏭\S{ Wn)FdT$H"|m\M'H ownw2ўbJdrm<ɟ47)/F]ұO]gI_Uז^Wտ=һgAdY qI )[7o-G!D@wO|- :8qtM6H%%&ޒu ހ&!k LRKrq&;5wrg2OB1q{-*Aǿ/+Yŏ(- @+o QBU<ƨ*7EN"r$,1D$F( :xeI@6y2ƃO!1xFR@ٟ^t$QޗZ F쩼,NWOi7G$mgЈ7^{MZ)PzeV tO| `j׿ n%0!h7qO=wO~mv,땢JΉIeW._v\`Swg˗γԽy~~m.xO8RkuLXi+jdskUB A7F7WOH|l0>=b`m_w}RD`% o{ޱ{`='=VۑҹW,2AoKxT >hQ٧2E.Xϋ܅O*S\H@Jl%'$(q t=RŨ*k2I5Cȅ"vbCØw.Yeg4'X~^\_c;uy6zǂMǹ+^_W(_ypл^[_';` W66<6DK{%|}w!|77_^_(liMnt.-yC6PDزə7_W{oP3 :GSI3t^fP&nc~F|f)&:{B4@ ftOU#]Ɣh zgTemўh6:R1C9sU ,cơXC JycSk8)<ˑ4*uEB*孊)D 6`AF(ۘPe %ŴxS)U> YV.CgyUkVMCƂxJfQx+O*2~B*C_n'8Ҁ_;oY!X_CU>b28>hZZRzKNQ cR؞L 8U_.OF/Q20B2k'fOo `,p@א𸦨 ,v^"ƽ?D*G=_V 2 Rv4kt2d*ε1(_3DpH .  2hv#A!*oxZ@1 pH|B$4`Ace* liqzf;,?SzOγ񚚭;pq7׋k(1>{Hq* e!`9J[^FJ0p@FQSL6iYwL?+&)6.0 cI?|~kyK; \x!H%M4EǓL@30 ``JŃAm}(%x>ΰ:_e 8|G!@CTSǘZdH2Ǝg;WDk=#\I6_&;7.߿]_+~g(;>z_}KU@bafnNĹ_+ Ex>,uo4k,/9X-qޅFc[J08uJ$㐅Ҧ,q6\QӜpMQK`&IZ_Ey-Y":Fdb5ƻR7Zjd "  %lw(Y"?^H~ׯalpfO yNlcZ֑i /#+(R9wcP΅q Fh3dFEYz*90 )IXfo$k`q\dMtgMhzE8ў>8 qmfH~ >c*,}ZM1!S)牔ݽm~-ҎؙPY c3,-JEQӝƱpqyk]av˔Y'% eG5 d<,숩Qqbꃽ&I $#M6_6s{`3/(z Zk<}?qC|>"z F;ʹ4N;N+kոJiou**o Zi8v!иF!P~i)rYN$ᴅ5Dm)5zzw!9x%-7bT]Q5q<~8u%y&&t \h_^̸,aHh\@d)f*DL  ѱX{m.-)8 ܣ`c~ƨB!x|qZ[Ð\iAYyTUX_f=g ,Π}wg\{.#qA('s0u-pzg|l@msϯ,ԅu4z'n'ao7wҍls|g.< pʖ_HO?>I^33\sL0I&3-ETޙRJUY(.pPw+P @p c8!· L - ̈2Ι4+w3=\%z'~^9$L.n;a ބ{9Za񃟸 p%[8]W-eCF94e2bizQDlsV+&{RN5oR΃qmj0EUh4(p(4$û6KwV Q~TkKH:'t7FPth)ʂz?|d͢dD^xԟt}n0y@9qbȁdr1xCf &DLcPU+cr |c}3$-sPSit@6dL;( |+ ;1UB\ ]ʹڰC6I3*xw@/l}g^C>X{pPa2$H'lx$5CֹץED˔ǩX=+uxXuc:'iRhMLu;Y?gU U8]v?hmuYЛSj8蒨rc GMmh՛$8dz* \kH`l p2>)o!0~" O)bQ1. :vP.M"*w=Upv×/28fW) j$] _^aj"#S\MM }P$YUVsbz`f8RJJO\Q6sF(*J;cс(JA|*)sF {nXF~#wǾuo3jnco$Q*U(26q+ufj@ʑwV=C9[W^mV+sh˚nHVSl31;>7V4c3袲72!d,brǧn= XbBQ`r VӀ/Ep6 ťFV4r=9w>yqƹ ~G)% G.. lmsd>׫5iM8*eAB! 0A3QAD U /Js&xFZKecqȱwRrmr1&~H O2Qk*Uyq <3`˃+!fVCp;x`<ό-.lMQ*xsk57?41L%^"$I2*Zk#k:1pj>rX*hfGBb$?SK~{9}A#UMeb0k!DTa%TǑx&ǩׇFkԞeEYeK&x|9ʍ^_mj+ɠ`˝|h pzoo>4~zT?ZgMqrB]DPզfxTBz@ro gQViu>BSS#IQiS0Ҕ6wc??e{`-s; @ptv*͔aox9Nih>elPDa-!2%R,D!:Z+a%H4tFl`8R*N[m,8N=*Ka ":'6> 'ݯ䑩 ]ϷEb5,S;`$ Hq:!)E }B,z0L$pD8C:mʁL|.^pQ/6fDX(.L8xbQ( AFwѣ׮"gbCI %lN4$qq,.!F[xun mpآ<S'Z2錊 Up%5ZGiF_sn([C˲҅eH@x*=€BhyLpޕF.Ҟ4aR2:lB;Ko<~30pܟ_u|{`kR\Q!OaW2cP[@SLn$M.ӌ5+ wDjomEfc4- &7_P*V.+[gc˯MIPLIJ4)}}D1s~'2"+1D>x k~דfx8 &,@C&#e5;;C>ga 8vvôbo aSBT* I8)v)c%F֬gR0G.ٺ2p*r]4Y}) G2cΌ*]DueoLf&fsVoޡ;P],=s~0jX΁7>GjSu&'JF̒$dAl&$u m>Ҍ$a`5prIQH3ȍ%!b:LKHBT%g@)n,{j+,uwߵ;}q_lo\\͖3ױN`42`bnQ1=^Ş+Kdžqxq]7%68Щ*Pm)d\py5Lk]1UvҪHUg*ýZ >i:*S1r6KqlpV*S÷Ǔ` Z/2 AI1xsO?, .kuR;SOpx:ՓB;-&d,7JuuiLEsqB#Pz*U*tn]i5R]! Sf~2V =gbn;/h^qzzo{P}'GqG^;y=YgHpEq>p"gը5t::Ap[9M:@ i uH3PpƓ$ 0ngP5ey+N1(p.o-]]4(qM7tG`*HHh dL)S 3dTȾHzgZ<JЙ:tAw>b˯޴=tm1sY^ZQS$.P/8ahʂ:€Q.k"J<ƅƉ#NVTU^q6NDJ$0 Ŵm?sFr!Xjt#ڸ38D $o5Q{^H f;8r* G^/۞]o|lЕ=.6k`$.G(A`N5 j} $dTR">Fg( ׆1FO}\4ZgU^BBDԄIZ|huPw{ۯ]}n--n?P. Zf^m8VbY45u{&l1=}-@ڦOx>~;|֯R9[zi*Sg;R 3!bFMy1\69K듂3!L;@J#uZ߀bB9aKbHy 7~AK[rp#˲ʢr.Qr Gk7ׇEb41@HZNyI1KV( M3&JVAҮ1871 f>w8x?K:Zm:apn7>xU,'1sA:h:CglQҤe5GqHT"{d׌*ͭNZ-6^_wF :5{$F9~5_OO^}7Pg 078-o/.7۴  T|w1nIVTknk9DEM@=gթ*Q@0tղ,F#aRj#B,-o0k_=VZ(A}KXM~ Hy o_n{ ;cϿ濆smL;*+`<-h`ʊB Ͷn--eY [j$R& u_k.K1<`p'ܠJ _Ūup{+% -Ҧ03"|Xpʇ)\ j[ M$ZjһP6 s)I5 [2V;Z*.kRj^VT4&J bD?7WywV&Г|_Oކ'CAKu*g\.5\xRŸ.[I(l(SϬ],`QB2ۊ`@"P5l0ܯgֽ7y;y_7Wӫr;};އ}.oϺumK?;?Eu>u:; )ms[^_˶7B6Y֗SGYqz>yF`8+  5׻c^S>R4*3 Wւ2>Eɽ^d("2;_6g\&J r|r߀{M?> i织2ZPD%+/|qM}>#E.pZ1f,k^Z̐1~,%0#\j }[t7n=~o?,\O_C>>7pzz|t?]߶bˡήb밪|w{O^~t|p8Ά-xO4,tyo[.E]_Yf; cdKy=,RbǐḫĄ ++2X_&-|w)s)-kޟOZ.;4&.ܾx=""!rX,'׷~w E*xAyVԚRh湬WC>#DV(uv1$Q!DunSORlm[2E*?"aG-qH`xn/"b YCUNyo,;w Cqlؚ׍9Ow~V7P[.p$Ek.(5TC>0g9?ugP w ')S$iYc>۶NeKҖwwx/ŧ?|}ͫg:sb*Zfя&{ܽpo6 c99WvΟ|o'۠W& .I5{Q=d)B5am8J(gDh〮d\,޽N*AvSA˺H^uV.H\@B!1]x;$߿ru\KɊ$Zi]^νݸ @ez:t#/eVA C1@j`us!5JA6(l<,.~x<~$?)TI* hO,BcJA `j@UCO;Nҍ 8*ZvW0Uh(9Q˴.!Y=mۋ\Ԟp]4ؘ.2{;]HiZ&=77Ӡ~ \ɴj]hŽJ72B}5`P$7^} 2DhPت SusܴvZ>F^6Si3tٽׯ-W_嵳}ےN߱/m4n ǷY^/S^kśW/_vu|ysDd.%.W%=>W@]HbK]D|{/ j"J10HS%g@юb.mIck5u).phTRu%Z59jfBf l!0C1aC(0R@V,l,d׭FIZi,i:3S^{g)pq~nóHr= ARKjՁ\W{ @+E ]cJncPA݉5<8{CA]m7(z|=/Oo6A`y &`Vn؍̓l.+Y^|~z=z8Kݦߜ=0vier6f[EzH צ.Kޮ:0RsMM]7XXrv]zW-b-YT$lM:j?w&vKس hX%O11ʒba[ X}G[jL8*yYY'tZ}¯}-H;H>*n@ۥ 4RL׭vcH)*Duh"P~Pk[eWs]HZ O>_??7|2@ N,al`ن;d0; DCO rzp~YDS ij*Mbk̈́s+~yKjqxMRY~+Z@ L c9xQ`PLp]*$\4)VNM$I*#ipĶZ1t;ˆ\0VLrYH)4\khrY:oV%cd{#bХ|j",W-~)IDAT'R}֛]kŽ5ŇC'Y-q,Vj]  %Eh: FIcj~g'5L9 ~ic cߧxdKAcG|>m2r6\ ia;,S^Si G]6pbcFqniP1km%! "Jl0i!+s{)Kd!!} >v:0'1Ge^ԬH1Wi[bˌh͵h!a`W , $\ܠw"`[ֺɱ@ .}턆?W5>A2(zDP()"r%QCЇtn>rX)5 DΫ4[lH.@@Xs(n7"S,EKӬU>F!9j#)DhlhHQrev1 z,B>-#Z0@*nE~!hE\87Aam/vΙb:LNxmi[hKX׹`3l`Þh C;k?a#_MX}ak͹J@Cq%Y$a TkU[3-! `i% FeC䀴4źM' ZvEɀgBDO#@QOΟ[K(ݩjdB` T}Ȓ CY6BŊ֫[5Pㆢ9RemI1c\s]@?a+1*ہl86;$+ PO9nR x;7”:MyWxl.`tcGb7w;&J%!̞|xPR0<R^=+rܭ:9~zIJyYJ^Ɨj a"aT j|ǁ9ȨaªXTcVWRD6iQ$Kk݆i]5# Y8Kor&7L),RK?r^Jn^v575˪nP\kNayKE`HE8%F>TN' /Od( N{+w.?Ԓ0 )͌0c K?'_R?p=Op! ףͪ6&+B~ AzkS*ޛ}p_e-NTyYn7/ 7`Ҭ)0XZҲs>5Zy,*5r~ar̫@E-I): \TZf9&} $TfHi> !@4sV#àɩg,v9J 9RR D;VC?4~OC}PօcVZ]n^y/?{dŽԹI~ GlYwVݬ{A<ِ0~?zW/8A]'Y[a[!Ԭ-smXm# ˂1c Ա].y.iֶf-CoiGE;M@N,8zU%S Zh(JaT6 DTg6WQ#^h.-5&je Vo*NPӹP#3R򮸔xT}2C78J!Ս!AjVZܜgs{7o|?o<~'_ .@Q *aW'ǯ?6xEjFM7)O*eޒ/:aݿֺR"z2r1L]qCT(aeE?JEy]6 H)`Ț,WG^Eeiq;o..`(«.Xs )(5Z`"K`D|]1T-kF]QV>VA#jU@1Z2DRu}*K6Ȟ'~~9 VԳ>dXV4Dx?wwP:  ([Iӆ`V^)̢]R/>:Tm pu 8-O?㏞~/xtcqqѰD=ޟmθ2ړ31%b?'cY1a^^w *Xd5+a] L,A<rZ>v[h.R_*:71mcKhDDadKS)ԆPsP B {f(mAK" M#k"L/mќk-"J7Tvei}bC¼Nem:Į3qJ``Hhɢ鍽w6ct'F6M, ξٔNVPճW/>wݦmo xQK`L4BZOT2B>8Ƴ6|7Ŗf[rއ@|HZ <6ƄVGڛDꅐ ThMj.eynR_7\mwݸ>mƴ鼉+k+D10nӸ6!(rB&AcD sq"MA+ WDleP1 r(!Q7O2ܲV۾U.@lp4RL&O}x ɽϳ *VMmx-#mB)ݭSL^_̷Wnf(p ~~~FX-vV"4yյUP:xa^?'grunrvɧ_=P }E/ o7ߌ䒘Xڭ 0p_{16qm X k5& QvCFH) ov݅vvEH#AJ= Iq%lR,8FnA]KRE`Kk33Q{ܞuÎQr Jkn퐆OH.[>b}z;W@VZiUyH P6MH~^EinjS\,zv ,gG{jYžZU%bL)`&#(P~WW׷oPUJ~W?ΏD=WHyﺀwz;|"^,ma-Ykw Dnp uڨQ86m Iiӧ8l;BphcŠ{Y}r$YŧYsoH{hm+?T l,+)bmUoBL)c/0 uRuS6i.S Bkw.飘Er5<Hx;Mj+WEU4,53BVr6pCǝgL)t?Ϯ5`ClMV^- źbRM )V,OɥUK@QViKDiϖdIu=4.v}  >8ଭj^ Nv$@וܲ?́-}w~n``@A A_HVX|謦lzcrRm{nؽ@JF n096޼|ū/.U*~*v1!O)mMܠn\<4>womP;\?6[8j [iۂmP!$ v툏rݫ!]5ù~cdȥ"FpR6h~TReÀҺj%X˴&T3*ԩ@+ڠ(sYJ;v 5B ]- 8l bb1dtB2b]mgN h:wQ5Q1/1UJn EC]P-jKJ(Ս@3sVBt~/^߾Swl.vC8lRLt5]yyֶo=".W!v 8a]7t_-+]y;HAG hC6^ QRoKVsW bQ"tЮ.#@pcWщƆ>kO\RUjIHv3ym57 buqaY[ .ˌZa>C R 1p] -0PFiCb ,f1F>L{P-wC͉a9r=pqdH!Ebπ"iJ'(w4j.1(@qԥR7_\f8}u⯞~g/ֽi]gD؜C-)q"in?!k{:r1pφ{q:ZRƔQs>O8P;đ|!ty u}m5LJf% B0Ggդ!k\*ٸPGgĨ̦`,UwLJ阋ǫf֚8F]W6P0hAbVHQ\\HkP8H!ӘBdN)T34C#2c-DY1"&X<C,M=U]i@!~ׯ?T)]''峿zu!CB$C]CIq tZ0le7]|Y^?;/x1/5 {f@vU'Dmlɕ{@4%P]BP BNWql>-o}hWz:6ð&jQ&L,A6R-~.F<ಖiZk61U*ɏ1"Ta,0wO tϭ2*MШ+$a= B/j? yV1!VՈYQP(* qC]hBZjɋ^މq7SG/Lg0((79/u*/Wohث՜aYd.u%oJn-97m@Kftm"hriF, mx])MXHD=+PꌘHa?\[JLSiPI!lm@K- R\ 4E {o[6SWvXC }dH|7㧖?h'rX5&Tyߌ K>|o|aŗLa{~ѥYDcв1>)HA1rto?(b&At5|W`!v|FOhUEŵb6[`Z}e-\RsGY&F^ղ6@1VupyQnbC I cȅ%ت TY5FKPO,xxbɘUenmOHf)_A"5vY\9)0\@oy)H+fn tIJ@+%f/a)n^-}KFo'٤ncV򻟊ʭVH 6;oND;Z-xȧ܌pKBL1/~z򾪒yYbAEkYn.ەyQb@5{c%*% ֞Kߥ̱rWj]oM-wF"_jQ6\iƙU|:RGJtF ڌ۷hS*T9m`m/x3UZmh4o Cb7tXo5\R]9 vs"wM7]sg ]gDmbg8P"?wy'.XU){}8ʒɂQ MJ(0wc D- A*EV0 }5Q1Зs{k+JڃD=Ԓ⾡k벖y^u:LwS-G?)d1Nԅ`!R>qa{pi2HLCJ5&bu¶k]Ax "Q,~dMC4vej nPvVEVZJ<+Z``U/5ڴQ=!VZ-  %Ca7}1ʚ$5oO?zd9nR2޾RB`h-Uk`f#K*UUE%q*ٲJAscZ $ZU(@VE*fYOje]<绩.l"5I O4bY%w UFAq8/&14 8h@Km1FhA42,+A!h@nMC\1JK^_|ic>cUlƇ-W{߳J-=%=[|={:e+z{<|Moю&}LԨZpM?[;7^~y_~tkX˼_5G؎ beW I 0x,͖.>S3 _|"':47J(sYԒen:˪9+z̋yf"U [2iL>6?m Q0od y=T{+"6ein 5sGVeZ5V*GCjUI%>nS~Lz,R/]{_C΢L%REJ)DĄUDO cXMQ%E%oSw>}V]ZaFh۟(*Rk\]Edk;4'Cr#S*ZbpeJY >v zP !5$6[fׄ@P;UV7խ-5fH=!0{ۋ}vvws)^ηn;"~WߎCFZ02Őɐ*A<,gaO]&=4V"SCimI5 p ]kUU pZHsVm+##ZVn|E%Ok=L~:ܬ~> P`Z1po^v>yysw坠sco9nφ::k[-E5iStm10 TI6F''NW4ZꐓR~5q3◯ Ԗ%gCo1ӡ-d]J=<)ݮ% '{H(M.zd1Rƀ<~ļbαtTʈ T*X\Xփ8 +Zj)4&޾:N`0x\Vj>X0&>W^7>/VkА޼z_IܴGÔ_[ލU.#HV->yݯH]Pۈׂ, "aIcRdz(!Dhd* kD>Mm2eѨ|^{y7\\qw˺MqYfPs0acC~"V}D!FEd˯)nqئp=1M[/ciG24 *-XeBU&)cYm/CZ;P겴*]4Uy/|>WV뛯[~VV!,l(^laLw˗{>0GjYm6IC(/B~>ΊkcL P#!0bDڝ\"֘^Q˫6O@}hJhQ e"6Y3YR2y5e󜗻bՊop-бjP7BedVp@O 4U5KAdJyh*eip>w/+*zp2iԯ%ƀj#˶d fƄHZ&@ h`ֲZMNʢu%1 cyٴz:2uhP[\0T?޷[;%e[Kݖ[$]&O1? b|;T#-oNfE-QWTHxͲDѳXtq=!YZZ˚+13 ѿCLudeu+JC<ID6'h ua#je^z[ :Jʇ "3( GKzMb^1ExboNgןO$]n0$e)껫:^qz!ܪj q~9ngcq^ JC1b અh GO5 3%g-1Uw B\HG d }kƗoc#qn7EYkX>.i5a|9hwj[[+[,4#NY:K [FPe"*1N*˝w㲙 pk4al/k5:Hh,[5Vk!rN Pr4njyMǣ1VH^;|'Kk3IQ)u]7ÕWa>NӿW8hJIENDB`gift-0.2.0/testdata/dst_crop_to_size.png000066400000000000000000000404201513354670200203400ustar00rootroot00000000000000PNG  IHDRdd@IDATxLɳvǑgeVy;~#HIpɞ~jj'[RHax簗^zpv(BR8ZPVlu @|霪LGf 4{ϩy27W\PLAv|6#0J]}N|[w?{@W@P!4*Z`UhHklu , (jSe q9#BjAH((tl&)#FO2%n[y1( A+R[ av܏b^n"!++&l"HCGDD  O7O'Yn^<뫳'BP;S@j!Bb HDdľJ%hiBIT;( d @nvH˓X~dkGhTXJ66Bx!%¯\r^l%E"v~d̼ZjG%e< I ?gW7bV' mP@V $ *^h @̂cheOaցHcTƥp-\jIa*e  0Gr9Nwq 끫D)0Rl*2RHulݟ{Y~ aw|- F!&luNqv~|\=~gAc0?6K`?, vPfY~ ʢ,@d?)A>O_T=["m̕ybA!QX"m" ˰\g"7`7mEqhM*LbSD :Tz9 x DZ=p{TaI4Q՚r,?{ez8!H@n!4}(S6q x`ƀM:Y{HAB5S4mN?02bsR(`HZ8.AHA)SʄhO0DNNWη㹙3#Ln*H1HLBѺÓ7<(>߇lAlC Z?= hiE=B|4 8bY4*PEpHiYuE!xbCr}y3"a@1e;,AQcazt~i^RC03 @oii g9oR-2Q ogvA*[:`>={wo-%/D,.qKTŤ2%"!`^l7'`gP9aaƵ 1]\>N0~@2dzl/| 8ZK9P^Xg.hh_,JG 81rHn0fBz3#ns_"qhW[3ʷk>q0ǜb9Ph)N/K.ƍÇ[ĉf2Y5S>Y,7D"|p8dGH=I0]?x4DlzHcpw~HsJѢ%Ҁ+W͓0y^hnTm)""KxLZsTZXJTry,ڏ7{\`b6jL{_$,<"iƊ*aA?[;;hAŁ!02Bϡ`HI(Fsi:X0C7e6<ѨDXqZi4{yk{%ەHsƘX7h0l"maB;FոY\04Sj,wV? ܏q0wXa: zl~ S zGR=O&jH())spSr[TD:lɒ}m%PgO?򷏻0 gRºy2Fwp( *WvV=Ҫc0t (z, TQɞᕢ 7 5-i KSf'lW!"26u bDЈ(ATF!Q-x٥_9]7`6<ʆ#y}g;;~ͧ~_W &g ۙ)#B40(y~~i@Za - R#a1Xu"4A̺ZPt !.rh)dvgh7H(TJ洤utjj\հF4nGicm]:b w/|MF:on?'+D=r&2XEY{ȖߚGeA)g dgn8=;M/tr̞-h 4RBGt$f#Fɩ`K†,kMyBtclԃf/1j-3F!MG쳏{ݛlqׁbdn,8nS4yK=ҫ@)x=x^kor`ٌRۈ}ﯾׯ~sVmRK)ô=niqym%7KT~=-Xf Y[ 3Q\IZogy* z,WgDCGsTL=[/=FubgZ )^t(Szy3d)}c=Dg~]bzb>a:\ooMPy9E4HcaQ0 WKKu۹u>Ic$Y2Wc!i {.FztWic#{{13iɬUIf rho)9/R=B8[(lGs?/^UvпSgWߣݫ4162{{ ᙇwA/״z9gq!E~R/~7t}_KQ>wZՙ @Eʾz E^~']c+wUcqYp!6vFbp ̐ȣO0Tha Z` qw7S/:ôPz].A( (gH"F0xLy?5hӐIySSW<럮Nt9{q\.i f[D%^~c8Q^0 zO1`6\Л! aU 0wXCLmVwW=x`W}5 /󢦑DR c"!p R-jaD;fCU˶?Pd:y(kAn`oiJsS/gv=QUJ?^> :#F 2~4o{)-k ̸Al)@4f ~'!BlVC@ȖjhD0`biO?}xvyb?0 GZ<4|#NUn>-c~zV0=a]bq)"0 on-Z0>>ˋijtI v("1ٴlo6]k5 Z(֊LqgW~Ű׋'fty8堵5 e!HC F;5wa Υɾ^wx@S".Yꃓo{᎑gA.CO2=`sA&>~:({ze .jru:/5 ʹ\,9-V˓óti{.AvN*̲}g I" !Kʞ ؂sƳtŔZ>?OΧopv1,PlO'/?uY`Gxwbw8=љ<73o;#g۸TE6cB.ʺؑ.%#0,-B!^Df,TW(S=/GJa3գ:G aC^0{;JM׉u qr=;|;rx/l2=j'SYN-aX,to'?YJ7e? xk!dvpd~yֳj3[zqS. ڭ3Dc"j[ p-U?ɿZ AB㲇Rq Mf@ֱM+jva39 5,v ٻ|o,B:mg= bܬ׋ /ىqYOU cx6|xB~x+x ٕGfPfS]I{r lNMaR1^r|H*Ű7#+֦KN<6&dts4Z6\@rsޛ mS@?~;_jR[ y1) ~azxK' _| 5.!;f^v8JڴzКLD{r^c+a1/_.֏٧W< TK1t\*Tw_h-Jpmu_b{vj,=`}OEi쀏[9 LiXcun.ON~oe%| }X X-D?`wzc㆑ַ/谓ŲC*6WYpxn]dgpbIˆc-Ե^DbRNq[;LW9Z,汖tNq,XKbz6̱cayiٽz{oբΣǜ)2gkTKtxzF˺[/ 7uպL=X>6_=L^W{؛H')Fzg.)nItnڶm^u<\|]qmRr}:6Pfyc5HsE9ꠋ;C^DkYfgt-ԉc9,tljOUoH;dgof'l?[GCgM^ɩ4.djxH!?/_پ\ir5@r<%ܪI s\j+ER*ꨁ;'-.]Y47R"Ddy1o{/~]ˋñŰ$Tk{f1@-_/7T>PRqakn_I E+;3`t qA~VGkSJc=ZJa6+bz GƄDgŔgD{a.\+ L(I_/3x,=͋Yܸڙ*{C\.+Rjc)#dz^^{rsOvgBBxhtk:vXcĭx1%oE Y)KPX*Z| vOjxK) $CHq'O?}~K;-σ6ձ\rB Qӧzk=[+ER^ tpm^_G-8BQhhgD`u}ڸòUK24&}X0EW1Qd>]8>JܤŠ*si#]0IU|vSn7S tFqVRRJy3 O)ϊHiwlj-W{O}A[RpF ~_k~mPGG/к<5x{\t2 {S`!y{n'17nOFlvwaD|>zEkj3חSW5Ȗlp<ۿp<=O7nWiWe[1"(GŰ&ڼw> ]^fbWgF[k$\BaŧE 0\泇/>[?=޽I:L)KxP$ >d WzqJzwn1AWYP_Y~ŧ26Kw2D ɵW`^:o, tQWEIEf/xߨOKI(*~PRqR}un* !̠'W//^}_~_4U2"]:՗wF)4bC;Qt~~J6A^ܤ Numܖv:Xc:ͮ(brd*"koBZ4jϓ]v6|]yauy.biNNҚ9Bi5>~ǿ/~xd'>\WOV_?ojiӛ).<~v=]R1QFjޔxgGɮQHP&C԰k\Yq@z,r逸mh Kt4\NjpX$eW  c}տ Ze.G ־O> qX]>¼_fm)e|tǿܜكmZlvA/}F+/ >pE!94,\H,@G>mV%ETfEsfH+]Ŋϫ6/rpɻfDYm#/1OoQX_ГU\ʑWRjX|^z{٫k}~-wHGܰ;]uC  6H^S b g]&EOy@Ub2yPYzX⌏{Wz.K]n3P_??8:<8 ׿xn>{ePK~NّXna.ȌgF?A@ #)Q ox>ˁ޵ h?KƆ=]7Ml]µتQ7/ DM4S߅ٓoŐ/YRGNR@Ϟ~z41XN&rȃluc.'f,8fi5'S[4).g~nc *Sq:{qOxZt/40":zQg8 ^Щ+ h+nu:.W:I }߭A{72Zq 9\$ ޷|8*.b?Ma 3n\>{ KB励9>߷ V=֧9ޞLja֑:VKqRm[Er@6w/^%RHVϟ cXVEJ뛗ql@ܞf\oL7JXv7DT,Ϣ}I/xZu}?Kڃ|ݝZGs+fw.mniIG-4\'oS6q3.9ڶt~U-6K:, [mv šm9 6x{ӹO=[~YEbbCL^LcWCܵ#rY7, ZW(m \ a#T;nY/xrݰ`i"BǛۯól__+ri?[/?9}*}-LkH'zɔ'l:z#m>.F_@bTH0b)=@o}*Ţ賗n^]jr_/=wEx"6C nd0NťW=$JJ "^qz;<1b xq8 Z/c۾,ݫ4S]HJ| H/)F "ީeLR,z5ry:71)XDZkkqTq:7O!ۍ!-4!R+CL˚j>ӿ_~1/">jnK㗿K8$ ?2M.UYD⺈~fUT o#rySwA}8}%AUnu^:[Cxtwv͋O^=m4M>vX<"/ÐbҘh0ʹSyӘ[osOuV.Wu2l84cVhR]R>`ˤzGsJujjw3Z}HE fp,eju#Up@I:ji[#>JR^j\_^}o4jSZ,hVL,-Xq?U^ d/ΞsЁ3n7-H2cgڌ|i4\ 6doKƮì[8cX#V+ ;V -8YP' тbTj^x6i~q2.!@ZAQb-$LC*q*m["i (+;>ab{wvJ5+cUro ,-`5c(EĬqQ͐>_a2ATCȮثZUk6A C^Wb/2-MiPFFbm$S0Ti)[p^--ζ u:er/ե*3ue1Kt]GtF*[萱.74}BZ,r 0w.K|pqzvqٜ 9{ɉ]tq;2d'˳i:/121ch,qhIJ9) V-&cl,ZT>={fWR44i;:χy[Wx1pU{9exi̥[4VÒIG'OWtq j옹؆DsL Z2n(շQ ` 4 +6҃{!u<ʢv^\)fLv,g{o|f{&^}:(Ł!'bs O6gnN}%Br8ɾM׳U^u^Ƨː 4˓QSʑS0˻(8d͑ P .y4@=0sپ$ >:<ԧ2ͭO0!|JߍX>1K1RҐ78Cj tt~l: m8XjVRś_=˧pCxt0,.(Yo6jc#؍a<u*LNvwՋ mHaCLi)9`̑['naߦE d/`թcA,'XߛM!H2;(FfsrX8x,x<e?}8n{S" X-wMfٗξ]"4ܩe/TߞE>|Ş+ $oM(Z # Q)AFoaW@ܴenibw[gwAD$(&mP  oߍQ!kL?'d͡+)x ݱi*Ћ]ַ-<雂<̳ }7$|dK[2QgPpN/W4f*-T NbFuFy&uV)j1)(@I*r*ޯ.Q%Upwq.-w,4CvC&Øy^u)9!uf2UB^#li"R>+$JR>ogEiQЊ>`"IMsG`٬-"]-j ŭӓū|y1Hl|4H 'Oc SqbF*rb0D",T#DKn{h!f^onM 9zf }=ji Zz$]_]ݴ?-ahj7c/0 9{AMKy<-/0m%{ {6Z!뜛 0u]L¾b*YT/uy!NCq"&)j_r$2sa߫7 (s\NȞ1Hǿ08sJMqӁ;j{!"YEswG >yC6\݈.!%1Q."fi(qH(?o]IC Jh^--/;~&v !S"L,#㩹Yzu+]PlpEތZ F#27AcUs\D_&BWYH+a!y߳Fhw#oL^SRǷ T_Usr_9Av5vҧl5nSbolG%" buqza/?zh3yrQ_(׭h4`?߂E"Be>⒥N`@eQ2}0rKmyQ9"=9y\vH_'} #+wSc_})KIqKD1"H% O,h9 r> n`88>CpEw8 FtmC H juз E!;ǼsG Md:LeG C, J훭Ȏ|c}Ő^>kgffLa~ aٛHɅ-8=Hfߺ>/+WbHbST!Kf*NY?2^ݤeL7.{N ܌ |j?r~|!G c8&zM?QR>ԧKwѐN ߩ=uGF|܎.6w{WϷmޝ^G[fW?5}wսPUQZϷ ߉o- (2'ڽ_n&$4 j|o\Nj8JD >[Pu߳|oot5a.wiُIENDB`gift-0.2.0/testdata/dst_gamma_0.5.png000066400000000000000000001000431513354670200173030ustar00rootroot00000000000000PNG  IHDRxԅOIDATxTُmّy}Ɯ3\F,_Sn hA3 O  ;'?!-XsKݒi=,k`Uݺsޜ3ϸ"\ɼɼu3{XE7|6Z+eZi09+6*vYem6HڜRJӧ65RVYjVVkc275 ]1gukt/VѵT6tf4}7KE?_|opDTY儨|rΆnXzze ´|9c,wNO| kQy[ Wɽog_'}G.k]xJiooOOtLQ;{ѽkWϺej,*~AY!Fsa[w[{unή^|_<9g &J# }1Z;{Ƥk9-!r^^gyzer\dyZ;T- Z^YLA+f{6F[MFGXMMkoMy`pE}IQ&g͛uFL/D?7]6kcٚWk2!ZG?k֬U&)m؜g/_]۵ jY<~z1O9ihZ\-{UźAK;ue˿w+?L*bmj1<_,ch1kۢ7T+6{QL0 ,5TRTww޸v*&`[SM`crRN&giI(q*߲ҒɶVմR.+ƹbݻoӓWOR7I!̓ XClv]j/@N*5 3x1mhZ,;JɟLE+tVUoOӧ/WWoa%m;ݯ.˗kUwޟlBץd"FM?_utʚŕ/r><[%^yd 9/!dcVH8T~b V>Y@QQѸU*BxT8 ^,?5(1~yh[oiqnv~>1(sr}>xlȋkmrK5{ar 8䖌ĹMA]PuQn ._=Y-.͡1[[:=~,JW[{oQ?ߺ?IKN~W-/ϚrcuVld?Du9zG{^W0(q!DD2`DҀtq<1n_^/V]kT6DB>yàOCߵ\$m3}p6V=޿w.f>m+'kPtwa܄80[HOq7jߑ:[-YKbHsUZe:YoG~ve vՋO?p?5"ߴGVI]RY939jAp (R 8GTi5ά2$3|fj4ޙNvNQvVjF "wlw;DLʈmSXт}wLAYvm"CV!9AI>} կ?=u圌K:'1]$SPq `|`F%4*M0 ˗kz lVARnӑug- ]6 q+Xg`dCǮhFxo3R.ol&lo|3L9ʲwFh˻2`N)vJ+ uȯ)M^4]7ߝ\_gS+O7cJVCETL  V 1/sYMD~:묫pk`g n>[g#^WmML3%^%Zy)DȚ9aO aNDPŢVkφqUkg&Ug!W}woݹuzVYa0[^;e\׵>$iAb9r.O` r9 sUvlgY'3ThNuZĕEr`*Apؑ-tлiSz]ڮ' rʩDK7|uށIr9մ Ui -l|a'#36S7Oո,KB b.Pxo| 8uۣãNiU^?z1dm i .eX,) c2,IF.kܝγ 4)Lpz DԚ$2e8Q;oލ]wy}ӤZkxw~;_=t68&(:h]+Jrudz.*L І*2 `hVƕe$KUÑ\1"C⁥0COd֭φ2ZlARd:Ƙbp nkP9TNʺ5ջ t9b3@۴Feqу;C?hj/aЁ8N \v3-HJ gp)XrB^3r!I̪ώ.5Iex)~r{Wn=?ofM[/nwwk|->"+0c, |7Z aӰrͥ&"?aeFy~-c -߂ʡM(tȰ{.^[ j(d _de5a8^Yi:mg*0*oMm",Y/ݴ%Pj%Qeopt[W'/|qq{K&Ȉ=;èAeNyzzڳFEPF|z8D_Ǒ ݨ$լ &h[xO.Г J%1/WׯίN_>z&%|N pRڽ^UG6N_~uvdfkM>(iGYB-dY+u\Էe׶Q)pEZ"@,({,-In8 o:I9Ԃ5jwZbR]AbPV֑!/8 ᬕ$ 3S> tG^-;%P1kF:mGD]Ψ^h2>I㤷@P,0R-S}^($q뜧JY3سQ.N|`^5DŽ p}w2Volnˢ\_O_y{[$5o|4PF;(UPC'IK5< 4M9b]]H}<;Al'{3@M\Y,r3MOsQ9.`(@\^-\ ~iMRUZ}m3p2"o1iGcj>OnmwozHg0Dy%pkh %")*:99 bh4])Ld%;Gґ!xIڂzc'*6DGc0g7޾}5u;* FWh,*bb;būټIuG,IZTNbZ'DsƺlUK- u:HV-i;!qYCԽ@V3aa{7U9w`gS| jJ=mEK&{dbнx{6dRbo?GZ$RMB2gy2J*deYj86t2YgPBP8)L]uf6{qtt{/ 0p{t*~D |Y2/f&(ݲ II0fBI%FB(p=Γx [{;[՞S(n0TNt5N™ktN얐j&ď 8ɱsO tgj<(~7FaJEVk tJK, k52}x*'?7R~$}j.j+`\ϔTʑ<ɂ@iktda4f(Ӑ!K_ BZřa( &0e0~{ѧ?MMރ7>h 8zSS*f@g'OϻkN9f.յ7p8\T9d~f;;=l;cl *Q8C,s|Ё?~z]6-f1 bqӺMU;hǪB2e.V2f0*zMjnfhVUny_4u6K-I2:?0dtϖMfщC@^cJ}1Y1YC8 G ELW"'YEan>vQ)r 9Zkb-;;'w6jȎ QruiuZ׫rqurkX֩-72e^9bH*=KML3k&3ANu}UL|9$:cӮq &$t %*dɉ$&sLXZaRB܈ = !5bwU(8+`9eKCas FrZCR *F;z` ɶv#XϮ[m{׫fR&([F L&cι; 05%yȂ׌6ݣ[[EUmMO cLcfZ;--edN_ya 崭nog+/|QPW*Sڛn;[Bʲe0ge,-B .9WluSz+A)_8drNMI`BIV7MD'JܴpRPzΗiPq0)3yqh [0<W]z{ogzQq=تU]\)n+;WߤؼI>ةWuj5 v+bYjR&`yxkW<] G+FE9X8V@˱, [}EGu ]%KIbc ON{c5A4qro`4*2bYø ĝYgTh?t`8YL26}-Qhe»|9E9Ir('6'pOJx~,oކ\KEd$tr2*=)2 tb|@>8{`w'zZWmV bӱb> )ӷGK݀؊G6ZJDQ7ڐ攘(8 m]6%N9FRUxkBB9[r6@[/~Ϟ}asW8Fo֖Eaon^ܿ\i8563gA˩}Mek\VD2(̔.`ZVæn+g NQ M%S1לFмh$@ț39l,OȽܠ( _lJa +Iϒ:D@LrƮnmm?y ʧشB>3Y¾`!lDžYjyӪJty\_,W$GF> $->p7b5Ǔ'qs{r!`$}7iUUp`Kl7FmE8FӮٽ[wv阵d 囫 ֶ^c*i QW ]2Mm&xl7>XZvaD%F@?K rYgfpZlZ2,?!b,3IrEQUe<1gٻph͎>9dig ( g?/Z3spxf4]i#ˣ{e ^r!z6Nw97_?[ߤ.%rE䪏8}}3A^ϗeZ49bDVX2 ~Wv<(4]/G!mJ1'`'O糋og_./vEWf^UUn[휕 Ueh)RXWY7c);i ΋ WN .n$FY ;!+gU`*B(}YA $J īF;'". =*UfۓY=,Ն @Sh5 27˵sU7W'8-fe,(U3;Lvy=\pƸ@"+8ki1^W]jbtNT NqͫgJkyrzkB5NBt'l6S`SYȁݙd 65HX)sDV Ҳ$pa(+"+>BN8C'?FuӍ8SD(*Pcs&&@m4 :_\N/6] J9ؽq:Um1bF%d~3qlƜ0ƮIeHOZ]Bl$<W{MeLJwKw))CEoᣟwqyٴLy-io%AH)lR.UYU9R5"B(K9 H#p>jCh(vIlݱD0CGYנ-Drd#^(\h`bwtt}z9U9,e$9{[zDO0 JrXcZ:2aUywu9x.u&hՌ3f~q6?;_~up>sl6 9p"'*3mT0(]6f 1ʡCP´$0T 0Hm4V@(gdA^d![VsN823[UM|ގ˚@1 .@ʇ9GAb ~\FdF].ڃf21f {`31nϳ_%Z;%3tv JqM}ZB5t8N58h_5gvR!`M@Κ[s}Lk=zyn*0!aEz, L-ؿ#@e:I8# "aD߈IHVTs0ԌqםKjS#`("wWw^[i#)#+m_R8$%߫(ߒb ŎX>,a!r;Lƣ`]Y6#>M۷кKDV)Ed6g^֫j:BkWÇ]|3q˞։L/!I2ԛ6&@).#@x @uyk"S[jXgΙ5'(!BBH _)<*&[ۿ{w mBtDzEAT>-m0n1 H0@ܝu貥 LJ~/.cߜмoP ,^rZ1.%F4q׫p0 r(m=֣ItŔ]_ Qu>T@BelCif3YP@foE}Ng\tmYڶY7s+U:;aE MQ 57*<[-iqN`Wy, X+l(K˲7)& gp\KSky+w| 8ΘPx{I-26)ulvҙ0MQQ~6YqXeY]o}c5).-Ԟ*Tmރ C5j~qssr$1\Rl e9.uO;ԊrIBV I8!^ǃCg]-֟64h 0Yn`M*kURlΤ)K~;_j~tG1p:->~ܶC5\[*hfWӫeRTq4WU}v(ˉs\~2*[Z "4DH)ѳh7[/+ʺ$Y|~9m;W킅fYq!>s[qYRZƒ"{0A8=">\Wr} }Q0ekAÍz9\ y͸c=)1uxvvվlfuZv_q3">X lzݦ O_~슂cٔŠ !拓@+6ڱBt}z,[Vo$ML׋9%bkV1.Fez1;_^xp2 ŦJCݮʏZ Z2ha7]xx˄YuZ!͇hA6YR9!,j~#c,R951+ Nl!Z ,\Y""=q%; tU Gv'ppIVd*ͫA=bPD(J[6VrmQ n={l~ YZQSQVȵz5a Î vB i!C[7t s/_Lk3=X*L~Ɯb;v 3WV+4nU0Nƺ(ru\/V3Êm٢?6l `',PrXb,=A 11-բ9jP xA9A!8/ُa c_zeT"'RTE%,q.zAUnߤ6NK;?2gIfn?(FZ^p 2h΋jtM[ K7k髲r@qۿV默WTxϩ:^_m5vrPm7w Z`CеqٌBS12z;]kHIdv[z['EU Gtgp8+Rl#DPWm<6'&W,@s#jz)aN2x|Y(גuq=!($m!)ϞŖVRJs" !"RރH..^ɽL|,Hݡ14z/1)@ #k$'K3#YfwALHƴ]P<|h_$kh4:D;jVlx8,w zOv-6x|gء<̼B*g7 '[x0nmLG[.z5oם WV gKA7c꼵+ .g")U ?F E((_d=0D\{_ |10]<.ޓiԑ.HV`Q  &Q:;,~kcDa˱MBQGI>CDR^CR/&m;Qʰ˱)Wh \̖`JI5е:+\@= !شˬbXDci5Jo~beY D\//ɡ4aF[j">aA>6a1 ࣠DM:ereg V\,}mF4n`77/n7='}+l's썆b+ۍ}DYP\QD pܖNI}qٍsNQ4f,2|P0UL{p /2Hyyuχpة2ylUZbg@MBq"oݿ%nڕq5SuX7K$Wͪk/n^l0S?XI>h|Vn_8~`BeQ(`kF.T+mDA4)&Q9 ASRJT"N2r y2g9Z7'b˱q6zPE&o3O-# bB@*xS Vxf~ $^e+Bᒬ0jaT 'n5q`w/s?iSzx{3\-MSe˺?j]#piPd!?/3֝Hg#FRl`i:^x8YsG߻WZ3vz\^<9\i,+s*y}iNa\Vr+k'2h]GP VLǣ ~-reB7P:Wz :;. 2}tkDM"_ aC*XDdR bܨ zMzkd_SwJS:,9pPׂ?99<]7uVŖ^G?\F:r{g -lJd| p`h[>뜠֗W7 ^!e5@SdeC8u$U&mYg$6oQ`@=\+mܟ,`#MXŘm.BiW UT9{w-zAL6Eh2k[e6їHf3܀d=8$S=s3R ,a!t?ScIs$$EF+|aG|@6I٤^bwEf.ͼ* dzZvG,sڸvs՝3M{[ibҁ0(l^}ubPolc3V)3Mv!̽m.[RLU(V:,)i|Iܜ7al g-쑀@b؟"AljG&xKEBJڝ{˗g/~19yiZm+#*ПhS6W [EuR9,k0"->M>JbQE;v'Ѷ`Dʸl7;]Ԧ|{ 0MZʼW] U0y(gp@ Y&̒;o'[]9&6rv1lc4,`4(U^_GVי0i~xTFkluc'z9F$Nef<*] rEC#$ Sּ*yN d˹ɾ>g˫?Q:ة;0FZO_~(0sQERt4[0~Qk߹-"LaC2s봐F¤qfϟ l49OY`=,/W]YE(G7-1*d>e{݇ c`Ol`n;zӱLO"m˯Oe|ae֭NGz~u;f2*G[0rpz;lgӕ{vϗu]^M ٨7ޓpYN2OPj)V D^;KUJRMΗA"x.&rںȽo,xþ_N~G1&o^$hbz]C9)S66-\J 9U25/?d|4Jr-Y^<?Jus]Q[7˚ $:) On '8 E[N="5xp`b'c`*G 1wnug7`XsMU'mqvZ6o ы{(?Nov~?9t!|̅RMvz9Muq|PqP"V=K+ .W2(P<w+Bq63'fhyrqBN$YnzGvsn7WNʢ(3U7Jcױ#EٚM? _gZ+!۷rب|^>1md|Y\}0,rC!ҢkT遖7XMVLJ&rI"abI .J)Œ!o%k])q8b.ȅ42DL]~Ȓbۦ.Q̡Ek.=OiQc7&~˕Y&bqic>O!~$ރ#_|26ޕWϾ~i5+ӭѬeI秜 NQ UY˶;Y)vrɖM B4L?qˡQ3GLnUfX.^1QaOL*[P;Z=2ցqX=*)[P*}>HF'zsL[cLulI .e Hڐطuþ&mo/K!gdD 52ȔFkL&,K M{yژdo]|5ЃLی}z`QEV+;7)rnrV~1xԥ bs qȜks 3+m[,f Vql&ed"FȐ/Gfޜ˛N]󳧷F>*seLDoj}ot悮pr÷|ͳ_?xxuuW_^\lz dk\ɥQCU$v:)˪UUNOt&e)n&)^T%Ķ︗7AOdD^"`_\y3ArjL&VEP Ff|sͺ J?/?@8)C񲞟aVj鐳WMSjR:7ܔ8m&,ql0{O߹"ee GP<9xt֐q':%5]!& _-zv25zyWh8"nU_u }Mǒ*΄I9߹$/_oo?'ǧ_o~u+2K +MܹY˓Gqgqle˘cZ[O h 61| yur<3AiX 3X#ԗ!߮-͠9SHlv= ѱpUi1E)]]IuW|@eyT,~8~q gI{"FR7,'?o5[Wb}tOod )>#Ѥ+ه>1'}ƻ[>?=CcAXc.20C@\ }ȉ 6WC}p|yǟ?{~s)s_dz"ƂƂ6̺΄ ^s~`=у]?Oy𝟸M. ^=7+CFbpm| ?{}IS)CMJSΩ(k2JL` HwUa,yXS0-ƈ&*R @4;0.Ro˜t*9g+͇߹ayBʋ>O?;3?No|k~s@`EOLzchٵSg[q{G%ڐF2?("bdYۧmҚ6Q=mls/{qz,7pǔ<$@#%b>՛  Jfb!º󫋇i>z^+~ӭVS(D#"FF4FAޓߌ7wyCA8RAA|!(DY6H^nn=!z1`Rn#fۮvw75P X#Ӫ%Zh6ͯq4(><{-Wz<{o.oѷuMǻLwEySУ}?{4m7WM(Bt9njOȅ˚XUD7%>Fq"lzz32J9T19Am ioFǸk`[7p'1k|+CH?y[ϧۛp?y$e53k@&yra)IIRJ ҥ@U`VDaY%3{_3X,YKng뺡4My\2 ,*6Ģ4ݻ 7p"Goc=|tʿ/BՈo?|_\O xbBtP5L[է&Y®xPj1)W߅kÃ"I܋=YsIA ƪNmPj>ܹ\",5{Su$$!l^-}~yz}Nip4KMB3R SAxp5+`Ex3@ >9*谕TOJa'P]3OuPթN1ڔ^Csmc&ͩ+@4ȏjw"t??{ߠ}~Gs??_ٸ|O{I$l"]7t`UO?b: Pul1j).분19y.54l5'r)zU5<;?rγb}8:pyv?WmܧWON"3-97=]xx80M Cd˵@'(E(%|Ӧ[nhZMW69 kVM zt}\ngճ0dg$)ckV-9]prѯ]>NAjj{?3 }*06fٌ eO ۋ\FƠv3/(XHDzUs&$t{dqwlf~͔o.adoqokn7m>{t?޺3禝MWgl]zW}oӼo&`{`wxSz@l t%?gDYt i4P> E ,%cE{V[Y޺ /.?ۄwCzk!o;_~R@7;Oy!留th|*)i0p7 fÈTpC$ ek1_9iifz4f-o6sT/ލϾl\ o?~p?~g$7# ^{x5\$/cHǚqSIwS-YMS]_A|ћ  Āy\!h {Kl8enNIzj6)jHY暺f%vmZڬ9筋%}2|IO7?O^=AUj>qغw7rj=?*M0BW̵,˅B'd6/R4yʵZRjVbӿg: ™ot4gޓmCM"C 1k_[pMiRY}uoks}O0Z ╺}lJ mGj: 2i5D"ȧZ-n!&)&)mRns$u|{c??L9?/?ݫ$x`D=% LtcfXk.ok~'h,tm\4-*T[vr1]IkN[O7׉^3?x!ko=g7͏ؾ}{7y {PwyS&8T4M. s ".r1ھX {ZAoMNm}zqPA8E[ .m*mq`m"OYzhQU۪]6i"I˖z UpZmrMV7_㫩'PFOs HDtMtFܭDwWLNَt%a9g0қ|e&*#`ҘrKifCeNgl 'zq7?xv{zHzpW/_>977]7&;h:i?˧= b#"[ 0gJY,vkB ә僭w9:9޽vQoT 15ɅjES@F4אBZn>t\ҌM4fQz+$D̏.꿦o F?>Нo7_\$j< Mx6=@/3zG4$ox"]=X7zF'y G϶U(=55ZU5Nppm4]P4MsC}JSh1א388+Z0 #° Cn޳K_nd#?wcw1BwڜO1͘LP9Fj7{`t[Hرl}NUF2#O4X )ms >Ri@Dg =hC DbQtRu>x+z߻Im ^} L,aC99 `xY #)f32  ƾN<zT H謫Tb5@OևQ)mD1B'Mk.}0Ra*Vb݈o^!9ښh( s#hj,DR|L4UW{`cLdU) S4 JS)A(QTHi-Ԭ1b|lYZk1jpn[@ٹ=Oa7?&T9e:w킏>ПCk Q6},{1MihCvtWh8%xBe{OJ#D ^D\=`%Z|Q?SP+]xFb *Yu55?1`|- 2z^N'Tf㕖r0!c6ڠսּ[^h (4SEmq;h2iX7F R\(>fchSr6:%5F\t.R%xh9~.zaPh XojQЅۦ B2^X2Lr+P0}1YXi>$9=RȰd6^:=Ք`ܪ232H5l( R[=QkYų ǩ128O߀`qPҗU@Q=it-ӱ2 VIxSNIXAHن˳^]](&DINE)3Qbb䦵&(W s,eW&pVrk60cjXT}${+-Cu|̀ms&3}&aq*SЮ1sW d_0nIe·iӡf)&;3bhg8 "z_Rj>׿UL mjF޲;m@^1qjamSr1cZN+ B3'lqOF8/A_3&># mjAp;`)qWN8if\JL0- _IT?tAE)IlTjhR-t_BsQU7xh=mt 9itb#7~ L-\xa5ǨZboLڋH),Fi4jSe0 R3 ]k/nJmȯ*xw8܏iΥZt=8uSWyxRN.BC5+)ggy[3tR18d`Jg䠔J3!k֒[6h. eFodCx/ #D;2W|lyIK)lB[vX${G^9e Z^U_wcvȦ5ޑ@sJe)ϥ@{i[vy1/4W`I+MdGќK_n"V;xTet^Fl@vz|[ Sxߚ—4^kC7N_F+G@;v icAa5AhďDm< L]DEOtukt梵a14Jtŝ?b8 nL=[a:d b/#+Zz|0^! 9D.w[wT|0)8m5 ~#.hZSW3)r*IlⰍ|;Xh., aQܖiAИlhLs9 {:n2 9ps T_[]/E :tաZ'gٍhmJ8o'ИC-.*a7 HI@9ܟg<{&RթaW[K=2zH4I.|蹆.r| BoMh>D֭ j =XZfRБ{8'zW @"˃/朏%:2$l@5#R+#.LsM=*∦I5FpY &m 2u>ִwަuhLY4Іߘ1҇~ 䃒|2> t4b<佴)b)%:/TkE,ā5h-x$8FIiAځ\|+N}Y9lܟBh: /vV[1媇/O%]SJS6 (6v8 ꘗ&=)Oj^p0ݎ4E[3HqOQ*rp*Ced(ʭ5QhpbF9\ Yj`5=d qD³N+,v: 6k`ͨ͒ &F<1"{T*2r?M*HI{RA9\SmC!Ĉ(J\sB&[@/2}FQ .DG\!x-7Y-Jt?od֟owڀ QVE%e"Lpphhs+tg)Ŗ=R[(هcWRvql|؆!&DFqIfSmyT RK@.MP$PdWCYH-(= cMbSNuͫZvvَԓs~ҷ\!ը`3-eۿ'm-i$kP u4P Qm1/}bҼul5B0t%Ky^s{6H˅-uF. t`M`$x`أ9F\7G~q 5xBp@Dk^*H<*\j3hq]ViVHO-;ՅLuKG˚ˑRڋ# dzHpnVͺ܃l zY/"pKl莠~}w{)%8܍7wqX=^-ՕeK/>>kCN0܄}i굌dC-2J j?8aBap(><`X*XG >6\ †Yb0oY9]O>0 [Cz#K ن͊\TSA(U2Ӫښ*zъ)!G\^yk[ (fHyq꣞Sc&%i*R\qf$ijFZ, QoV/mCE7ްk ݝ8P;NE-qT#q!NB$WO7@B>Ya cL#R4ɧqPǴݳWJ.!Z90@ `eˬ*,q6m7ll)`i:L}2Nʫ>X/ek%c hx}kmk- ޮy| ; M6x 6C]}VtЩfCIrdmjOZiXm9^f,r&ɲX[A]`TR&[Xſ{./q74{Ձuڱp"ć͞ &y=9yLItj*VDN'\b%N Ó>J#6# ê7pxXkzL;n`ovZp #Vn#:^fx̳UR8ssHe30V)Z9%z>?ZH4P1u:M3E2{ziK[A7\H.gxvF[*F"ERqR .L F%}wOn-m]dzq},9ZsKLp{@ovCk^P G65-xG&Z#|lKeAEPpt~k "R"c]?<+6on9&Xf61Fsk*i1$&pD2ZtY/"*B!,R"_CmHŞmj(`!Wֺve PJ )F= .bfVOc}Pѕ^D}G0,)D%I|:nu. v2)X^-EוzubZ_qvg]GG/98cj>V)oq#7}uRO}j-RR"0dUKɮ@gϐI7K\$вT'G:酄g w0F b`sR1ypۄu2kqu mU, Y">2 +#jpY24myrY`H]D_- ?j~eV vFk٣@c0ǁ<;l;4jyBT;& ,>'WLd 4R ( oMTey,$~e唗a "6FZ%G0bX'1N6,wN8lی4X "'QGc"]GwyusHo$t /3{DQY}tUty"'f醋@8WM=rK-G-7i-F&V/#%c@XR* t 59+Y*Q{knʻT!Ah2 y Jʫâ"BKH |jç1e,Hsז/-czl6!9oީg I\=6{µ-Db*&za ."'iIdg*^p[Ok%fr)\brWf#,s)cʩTƭp]E]y]P]P5Σ!wKQ-Z ` jq>BӍS/큾~凧:^?0--b]V91u3g_Wk_ZdN.xlMN])8Lݤ#J?gBgC:ċ6^zJ !eT@=&Sh"T ?3X>rچpn# v;'"3epjĮdhuq13#D3U6+Ncy'&W/׻f+B$y%xgLpEvT;շ@OCル&c;Evw̕`z<4Al4"\&8.KGʡM6|)89RUNj ƶ~EH)VQS>}))_P*w\O.x fwZB:Ka'wؚG#{.FPŖ6< RN,Z'E- k(T'14i㘐)RS$# Е3~vZ_?Fh.-gp ןK 8Rʔ8O#Z z; !~h?u]pԦWx1Cd\Wԩ"<+\ym(íTE>ZZ'U_kh؏/Yن-շ킑{{Ik9&DY\m㐇aˮ*9>R.Eq(U GTw(rV aj@,JR&Ė)"0ys)?tUv3@|,=0@u -l5q z6eX3+wf`FQ_/,W}̎}aU/٦Mڛ Rp>I E#VL'ZmL>mqVEKNX Ph{f̚k *-5)vr(=-Z΄u.4OS*SthsRs9 ̨in5ZN%xu2[l ʂk 15fP؍r55Y\ےcƞnuf]k[덀=EjhBҠfX@,OgH)% <&9e$7mxZЍ%,M2% jq ^ȚZClJHvdJk>]?]U.=TKCV}GqK!.t'Ylr)zا646[zGQggg~76C|,vd;,Uv*/)P54Mt44k".E3R#H$,E2 )%O@4ppf֓q-/Olwɨo*5 ӈrr65vʼJ8"jb9rӻg^52W:#Yw^~IA݅4C- LǕpSnH`\iqИ0ʎ4(Ȱ A![0IBsgb+YZ.Db)DLd`I@!|N@) FY]:[7ͤkWx+Y~@́ !rj^@. G DM㈥a-b,Anc_ɓig_ݻX]F`k&XjNw?"Mi ?^NO;::ӷMQzoOZ=`a<9'M+k#~!&%۷nϻ?tU -.# $tsvm`zaSl>_e tU]Q 1'Lh`VQE蕬zq]r_V}ku=;x<;d1h#d32W<0V\Ԩ'W ܀OKpXEmGZ/c9+.VjPV ^dr׫.ͮs?io^߃qv7t}?yy ~)=8ۮC;Y}Ƀfh>G|{(pi,o7wMڦvM H(:RI.7`r[MMNN=a<]/Bem^,//nΏ4t~q-`ʀYV$I"8P9ئVJ9b!w銟qJEQ% m;ޯse>)$⋝6,Y A@P,r(MAV?f ,(O(sBUI C|g믿ҋ1t=5ayExKy{<6,5{Y666L}̒I뺛|OvZfG0f uɔ}}?=8>QUE$AduZΏPX$l1*G\./`R,GQ0Eq0ȉT'j½x$OgYDLMӷ=f[؀rhp4+{l2گo=?;=}XQ5 y[;Zq.k^to~G?5,&l:߳уzBմ]7N2nl6р릛w͛%.\ڽ΅J0s1ս "Wd\W;|l0Cݯn(B;tz29LgU0c PvS:b`rF*4e፣ ͗gU0PVY)2KȨUSlduJoP[b!IJ[ LJ|s9c]0c4IdR,_i?џ6 {?*vC \eFe[adA}r5;tr$'x'ힷɜ{\71fg\̉v^YASM=ǧB¤i&UՊ9<^#JBh6ƒ\*XތALID x*.ˑpi6&"~d5ѸQa!e[FT̔ռK #F!G>)Uj0BbeBEޜ>9>&G'ݦ ypyLnwv3ޮ/_?^.I83[&PI1mڤeZk' DWŁ rΌV2]bHpusqt7LG׋ ޡ>%"3cQU6OF?M8.PL(bD4 e-Lyo"3$:TW] ]k pMuju$U^ns<_=;>>B%6Q(-˒c`~o mۺnfA֐9R1=)NՋ2"p\Ά@u~WV77ӣC jdӖ[eykhD;_sa{#G[9v~1[KbxUN9,Л) H,gãzv98[$炾vEo|06vq* H2W(;+7*I@Qq7!HHej!j[HVa64rErd 6.i5`#(q/}S/ژE3!ѠBDNLq½{'p&'*T8nqᎈUλ0śŶ0G9W ;0[Ydp7UU)] *gᖨY?ʝ[Pbh£2St1V`k&~}o73p9МXwýiz~0}:tx: 6. f] d뺛TYs\W ȀoϻJ}a+yLygn7mxETjtDUw9O>0$[M>77p^,i%1υфU06D1fR,-D0x_YƘu"Nirdm+; #6m0ncWM1T^þZ * HĒQ< KQ7*hjQ֝aQLUFmg3 Hn24X03 >T^'9{cv@*"K܇nu0 йPRJ=;N&n CB^(Z %( cSQNZZ6gV4!CShESS $C,X7d;ð:4CkN Mt:6=Q9 ?yo?R/"pRrM 5ZAv;g)["FTsm\mmlIP֢J7_ZQum{.|:eB._Pcd2W1&ԞitܖB40g9b`.tnu9'~% qBf"`'R`;aQtF$3FYv?Y9}`f%!4DX0Ը,X!a!:h۶k!ňa1a 9r?~X圶=QV=988\v7xۙÉ 5%^3*%?,JBqHO[ufo}|]9+U'$~/RUP1˵&]ƶe)"=ZWWhIN\A路ĭȲ C\'i]O xS cLOs !T1)f 6c l(eIx%`YgI#CƊ8D1 #AE7x'N H|0;S"x CoZL(&&dMg֛|>tm^,iW~/%צĐ0dW-iH0b7wǝޮLDXnes@s%Eicx( 뷮O)b(z̹,2jj1T;n`k`A}E:3 $3oHE}s]ܳVV qhXx4%?o*9>qv֨+U'$Q a f]0%aKb Z1WAJXd"lU|fV jp.0.\ZO8lꦁӳOgt롫=昢 j R#m?6Pru1,7qM zC_57Dec0\st84&'@* 1fRu ,XT2l5LEpbM`SY-.'φ-m)b.n2s:3c^y(U2T!S,&;9>kӰ QqG$vDŽYXO[4\]xM'6zhHΔPV089Ĥ،M?Z#lAF#0QF*i^\-;bXil60-XzwJw ejJQ U-ϚTNX  &< kuXϡ)[STy S^o\b#Vj* D=,;(-FR܄C5{M;=y{ 7m5ASLbL#4ܙOdvCoa٪%t]s׈ɉȉp8] @;b>nWtncWG[B}1̮6m*rQ7)fHDZX7oMNaY-˷o.|?(WACvK؎mOB"am\QM8lK–ڮ.l+T@{MKsa+ny4BFa؆*BC-lM۝Y2;mÍ Qn('RB}|i۶LR(H|$4Uiȃ6&`pmWݷN(Ҵ͐-MއŋWت@W[rvs9e\yT#!QO4Զi}904]ͤ>hA]U0\, P1}gŗ[՞B4@0ZS#--j AsvDZ $b.V$0ze _UKLq%_izcy@UbjfWQyFU `ÍQBp1Ŧu5P*Ø"_\p.f=ziDh.]߁~cl]upVW<Ŧ夃PkP|e(8&n8y) SvaZ54]MFHGL唉|YٟNXW|PQjLd wRLGӔ:0sݓg/J)y71QQ5h2GHO>x}ࡆh;7ccHf jVD,8rX0".:* QIWiJvFP(L-$FtJՇ C]2j1v fK̆^&rƮb5,:UGqaJ9@&.E(ָ)$d/ #a`Ѕ:Ibq}z: uU5L~+"1c^t&0e=)7w4麚ߝ>{罪FhJtD|MI#kttָWMT用QYɦȲY a ` M٧B,xs"KЊ6K4/]Wi)\gwx,0vK'Ć6)#&T>QcE] C -,gB&O|䁃]cr{vZtLvJ:!}wmju{~GM3Um/VK,9]J<"m) 1`)kTP (E^c*G ,35sd\j 6}Zkvc}sTv/{.yv,5^5lp!)uƹJNr;)2vL .eݔb2q])Ƥ8VziTh\+TL)&d](@\}Z"(-ƻ=B AcswzPf*evV1QZ3dy[BJ\l^y&GU3ՊrMbhpSzfmRXe))Jl0oGZi no JJжrurAx6e=Y fhwE%'2)5--U%?M7ՖѱqǢv/mT˧RTb") GЬ;w fTrOCaBu \U;\E$>78UEj)5R8( &Xrquu/zެЫg[5#wlaUGh {\6I̐EQH)-PԆ4V\:]8BUvBDI~8Mm$Pհ/oh0vBCՔٽ_ r߈z ) M7w"9B\]Gw+Όf=$'>v j\x[O} W{l͠gTs{9Z~7~s܈gW i^-)!Tu*)囪:3X6c5%Y.3SV;ѐKq:ڵ\rb֖_wtot ^h&JF.`F&_y*KU{|-o=o+vZ0AYH ͙z5 c$VF=Z{z?*qqhfdSisƱq~{z$B,l7_lخQ ҘU%`&h뀼o{\hO&x/qGȷڬ9TO[v*Ί 1{{7*xo"HE*l{꿖,qc`,!;AV༇@ؐeO)!`qh=?sF5L3-(l w.M8 fCWdJU}Tס;_TT/~>bD+H $1]N2ʇh61׳ JEDԵ W~G`6Ǐ䠝t/Sm[QRQ*R댲GϻPW& nx-uU\2twW؉<@ˌz9hdrX[r{*j!'kfX(&RQ"n0B1౛8x7ES_wgѴ;oe=^ $`=SI&ycVF2nOo>5\ 6é Ê :#2UK[@L1-7_oNߜquppl 1<:K XW^2]8>(LmHe.;Y8Uߕ٬}.S ȱ}7|5seM2QtnEp:w#zcK{4RG&GL.h%(;25Ɛ-%ҁd[KZfgT֌;FYX쵭f{]~ST Q[(2h} 3~kB'ACb>.jo 3歆'֡7(j5(oo_ǡgehpum=#;/[ng}upemƲ-SZoF&] F'k~{TB"Ў@`LXeJNFɭq1JQE -ɨcnY.#<;1 10vuSfcCr511oxnI;QeL9Rkx\)#`.1G)_& YS%V9&E젚֓2RbMdjML:|X{g%6x7UAZ$Įx14VYh/U?tS֪NΎa{ƺyzw}]:=m+C]\Bą""a:PK$JL]%X}}>DM853"EAC Mpd(v1m]-Z0\6IdP ljL-OWgnJn m>6.؀vƒiwB_EcI?`!:G -0q)hjr|+0T>L?m\=o][Ev""(%$8Zw}!&zI2I'!bR֢0+ҁT3id q,l"K LƦoa+ `MVUW9 NգEXx?ίZ M_΂z=g]&}Sr3dZ$gw:o 7]34lv4*;IY:L8z,e5[CwI*J`zRKc 岎H"˱iRt ;)Swm=u'?xKmT;<&zJZE-`-[Q9Z^mL.1z&-f}T + 3cC%TyYɆmOEIδ׾y3e21SP/XaifS̩Di_NV. AT R=1T{uιPWuVmk(16ZׅHŗ;Z#Ԧ":zJY5,8M0|n[_L:x#?YV˛;TLUB.3&@f?8:j~7틟#o}{'?3cxI}Wu%NSfz̘J{5'?cv W Y7]sq|F2'mBX8Z\s|}Lj80ʼXxh9q `9#PL'wCƱmvq5W?T_)C܍qڻU_^?s: yT}W:\;ڪ :`р39qL",X'TO)`(@ֺiw-u/{pxo>@O~<n}&P@9Xrd0w[:4spx Cٱ,ØAY3c#?hV1S8Xt v˰Jj?LtRkerzA'JXb`JA_ `;~!]m.[rw1 ۫s$) :WIib΅ïTӯjuQq7_v5}w]w5<8- +0o}}"S CaUf7/w}ulb#xg _x6xI )曷'Ou NfѤN:!Ǽy.P+sI2臾Ўw;у~q9A"39Εѯq4%T7fK}Sq]!ж^n5VeqO^8LN?!hֽϹz5,rYR z"ի^3wz`bvj{uՈ&ZMm.#+ޗdXЅ*>WٛW:!o7qaBӵL4f)ab[jB5%8Na^~"??=( . d}eLpdx]|CZWZbKFgS!U1ϔZW._oYvO_ަ:I7̏Ee I'~0 k`I,LA?oe5QK/߇_{ٕu1?Q~~q9mU0?BA@P9 p.ҎiWRre2V .^4lm.J=EhƕVJ*Cԟ(}5W?r<35%A*+WR?5|]=/~,u>mmam q@-цdB2J<H_'0&!nCT ߼%6<~>).{/?|Sz;\,9oD P(fJbs2Q't08־ <%idEIGkij`c%*wP+rVO¶Mv} ɉ%ݸ9]\M{k*,yMր[eJ{Q/?Ӌ7zH\(F2f|;R]4V֮}r:nc"ت~:yPP.Y"ͮhI~*U^t/q];گ߂]S&*XWg~9ڈA1חӧϲuT@Ch_Rq LFg %w:ɖ1>(b8*YvB1x_m'yN[oGbi^7#Hlll&gՏ E1rg%ER{J_=o&dt&)Ċe:C q:Ha`PH16f\Re/amԸrw0d-m/\ iE޼=Oi2n_~?S[ :Yp_~w7UvK['LKwcS`(Cwaw/>[u~>.kѐ4*Xcc@͒Λ2š06K:O~l@uB"YCt{)4Sq@L? 82}Sry`L:*DuB8tsF*G?URJ|`W8T1g18ކ"ҋ(t阔:`QH77%}PDZ? ln߶^^~G6߃O˗*_o\~WZ(-b| dG";0.0-(Rg'i3s@,pdgWZ\wovッ>:_&1ob^I<%<(ŇD0@.k/(IIFLB[{<ܛSb&jr`wlZZ WAf RVGr9f#)kA88!e$rb3C_2hγ#wKb!Y?l|&&J. (LaӯGd @YctF]yͳfs>yagԟ4[\wbwxc5WEt7{L 3&ih.//ZiZhd2ԢD  `͕w߽%Fx7|/jҞOߔGbZ-:-r}_'yBXAKVw/zH|M pQ7~zwO?:1S<\V Am*NN)6En6K%U%ƍ8l*r{=o}/,-^ߤAhҁt~w|eʲ,5國zwhQ Qr^8R,5?dZlH zZ`im!ҺkjίjvC5v226A@&]dqѷw#egۿoxȷ_m_`2܏qP'}9RgOZ^a>.J/jBUN[> vF.58o+_ o_ۢ~(u1ҬMԮv*g L"՜C-gҮ?9i$Kꣴ-m;rϞ)NeȲԥĥZa 8C0Md#VU)SkJJ<- W9W^{oꈶ鄐(dSj:nƋYzYWBs*G~576N۫?y~wӗoW˄0J{ϟ g_|Vq~JSYRpqT=0ݫ"=W&oîY~rpc&'\; S޾ӊ*8m=I8nEw//u}ˢ )DD]|k~I1.Ze硅16쫭 L znDs{ǡ@ Ĕ\4h5>g'C tnjѽ;=rڻտ:~ĽxA=|~TOWWILk9vZu`*L9 N*ê1s ѭ{.!fC̚g+G?9D_?}_͟\I>S50W#x˻Ge >?|W?~e=&p[~o}}]M-iZt$IHB8_]dɳFw2ɪ5!R՜siTCsxp' fTG%;#9_?R|['Չ,F>0<oO6qoޮ?rOC_^2m7ח5阫ua%)h$5]K :5[ٝWEiaJKɭ_5 /?sϔt|QxgWO/{;6c]y\n7&ffUmeu}wkqN*xAKItwSk߻<`GsiZ6&TQg?АB|.*V/\x[xLjf+=̷smg9b9HiZNWZ^*ӳ/h;ҟӟ~t*'r3A߉~EL!V 'TwǶu\p"pAinSV YCskK*Ŋ˖s'DqVݎg0?ڏ;C3p}u=PW)li @ O`,R$)fv-6MLŷop* E#(vԎ{ʒ#1,-PXhhGOcL┒t8x0\N7le&kKlQ&ĺMg9;6rxK)t,ˉ@>ҪGJ\^'.RF,j>a7l.IZ2?+~^}f`bZ]PHyNo=y~훛Q4x;|_7~JxvVqg$+\^l!H- {*b4Y'/Vs'yI!J`LIҲu&f't,<W[BҺt[|r*[L{ht#/O7.N'wGtyqJ>%NώOÏ$fx@&>G(`' І b z ;mB]|M;qZR2b\5 +'[ts ?r7\/ɝgn{opKӟ~l7NSuJ99=;x+@U*0,bOnb:`>8 1jg-0 ysY]w_j>OafcM簾TnQ ԰Jy۴p2KA)ӾZiHlZӍ΃Ie#hBve\?s5sElm!gel\vM.q;>1Q:UT`T{ "rԕLPXW1z`v q:4H jcb53j@O\6u vN-ҔSFgimL\*j|^L|;L HQ>{I6H.­vӀL 'K}((I1hXe,:H"WIgWH4A n>{,@ށsclg@UN%jH,(@5 IcOSY}"8JܽʚR*k\+7*};:/FHjݨ}>O8}7ea2ZlkW蔪d [ʜJetj/CC@φWn~( jլsZGs9a*ŷT]R.PWW,{n^p>AUrj y-%?v7~ _sG^.|"a^Ւ[ ,4.$ >N-cMz&MtoJe_XҪ{®1C̮͆Rk tBsei`UX=˟:"c;Kw>?´?<#9- wp{ȴ)Ov'ۛg:xE7zo fOcg.j}V]|OJ[W4MoW m`TɅA2L ݯH ~蟖fwJ\Ns)0M.۰;^_)lb+vI g&JAg+ >|\Z̈s29^A=ώ\ N; 4V8(e0u^ϷgTK8b?Ψ&AzpE ,彯g?z'nI_ұcV*O,i]& Xa`Lep<ť(ljZ6+FW+LR^BrCMٸX&&Yw q[5U181уJIeO7aʋJ1Xk|oNG8-d&X? }i7c0FR$0%/_xSi9/w<\P91H5/ ?UKweciS5nLem5MCEfuu kԡ e  lFO&%B7'< Rgcgޟ]i7߾u9}o޽mCPRȵ j-lN;.8НȊJX}nZ=*+[٨ZB*KK"NW_:X4-w3fɃqp1nȹ\ )M ,׿?/gY~y5g΍l{?X3Ɉdx9MYUvphxUs аϭ7gqRmjPjͦ f oZv1uk7a NUkxj}YtO?{?Wy;ӝ\~ŋP {d | nTKN0k3e׊cXd;6HB-GJh6ޔ q1.\)t<篾//nO7UxΏ>Njfom C #̍y8ycK>p˯GJ);O^"z|9C-V[}w *>8d˫[}V!wW$ ժY[b]{A(awlK>4֗3]a:'#9Y i6FyGoolwʱH! ä斡Tm$}sZ6JL%$H.6ѩC<0ViULܔV KMIT˧SYIa-5(wtX^Nt}rL$P5Pf| o۸=mvwayw7|Tqwj ~|"bNRC}T{HY8Z{4 y?a@ UpPؗVwa؉(u@`n: Z!\kq+T>ZlՊC^$'-|,Ufh'4lwWC*z3ܤ> %hD"c 6Cخ -10ubӔoBVŮRT%ϱ! . )$.sɋ$a ߎlJ%P\҇vCEY" Jg v!We؋߄%]ꯔJ aG)8)gY<Ըwx1&)'c~6&Pv1fbZՍ>m IJjCT_1эYKtBmormolu#ZY\TV )hp%Ny[G"@R)gMPK/UZ=a0ߥqSBzHnl.P4 /֣FUk.%Nͬ ~ aQ:`#ug1C.1J!qd ʹ&[%|}=$&zQɡ ]Tl ,C>/'Ba%.4 qr(32%ٲlPrN01n^Z]0xs3q:[ p=H V@"%Ԣ6FyHczw| .y޼x"|@In۴ܟrƸGwK!:'4 epj,톀)EɁmdםp i$$v-Q y?LR =Lةԃam?tXoƅ|"Z 4]Rv}6( l#ײL|cd#S+"! p#1uVH-3}GHovh]~[%UUӗ\,Ip)*;,lYtc1ZaNqQTcɨ£ 1tIjʞy% B8] :E;dJ5CKsn^tS&|ccR&jv4)Vi]=JOblHKZ<97yDIE"K+7XGv}t:\=:xkZqUnHN;ҵk%OpڎV7Oa| $M<<L5Ž?:tqlw:͙&vpIZζ65<6jk-D, eH<l)P!4[40:0k9]6Ü4adYVe(?暯A7 ݗb282tbJBc em͏8|r}R:w՝V˥;,\}l.fX$Yi6-MJnz "wC".X03VLp4?7{b&^0 i܎D^2Oëg/߹,z{p{C:f]=V yV3N $SVAu15F9ƈdx'ƝΓS&&VA.˔k2[ZUj+& k:Rz>3GQͦ\&au۫"c0ijK?ܢ)y(B+cxHX L5ѷ(*z;jv4C?cwJצ}f j;H:8ewO& zvd;gg8{K*)Y8Mti)y\㋧/>? :M 12Ǹqsuz 1Щ,wgUvVfi1Cr y1~0tD)P_Ł*@D;N `W%wO{IW5]̦E+ŔV+`xBla . 8&ю- ?m{=ù,`"]L'>ˑE*5Uc6b"b/$d2:@ON4,Vg"{`D~2*֣dŘXѴ>$‘ZZmPyݚ*SNTt$|nlU+[*ʪRxeJt! q+qq9 Ȓt{2Kd3fFv`Me;ݝ`4㜎s:@rf:i͐摒͕#mZV[N%wcokI>P HW *͊ iVN(kVPx6Һ*vAݓO-Psú"Eav5ag)+i_'"DwMq,EP~.\[6Q5$RuX%R:ڢ~@R9--3 _`$О/ F>̲RE"`@].A@ R\v3oYO=%߻ɭ6p6}|o/˜" * "Rz!O{^n3}Z*Zpa}lQ7;C[9i?ɂHwĶMH-:_C\2r{Y{)Fsn5I7 Bl~(TDX/pV#V3s$5~a퀱BK: 0|pڡz^2 hXCq/xUIƫ0v 嬊QT"pZʕ[Bm4Va>L_H`O}/#+fok.Ǜi-RClM : z 'V1@:H4u߮?H߶%vV8ڸWFo_F%@e!VQ/آ-S\Qڣ)Au b{yP{[hB[ {BjAjɎxeV8V{^g#@tIPGbFdB:ðuى]9ZMVE+*dnQae1 {KiNȨGdVlOAJ¦S lx-ӫc%CJ6lᵩ' =<6v6䲫wCV/'#-:ү>W7ALbd؂daV"TBg<'j=-$eYv[&M-r} c*"2x{`H5O2@+R5^Gd"`sF?=O*ΖHmp/ju1D[#6CX]OP ab1Ž<šH ˶oh5ZjG 3uU J(NLJ jYze-~ȈQtIsJf;l[O)KOi`l:ȼw zxyu?ߥ c0<1z3dG[3@GŨvvQR#Ck]8v1\on1 ;lއh ӬaD*ԁ*-cJ5KK$qb[@/*`.UiVE=Ç|:J $"59-e)8͸]uF,I-dIǰ:N\ctT3ݥU>znBKy积 zqKIfе_D%SOөo|@lS+c  " xL V- a Q2to9ܭvZ&93VJ (X{bVX , *ĶQHG\ &v ph\͍hv9I"M[j-söw"c'gzD>V s'bcu7jQ6Ӓ2B|be^rWZ?'m gi9n4ϣ./=~ ZV> :KVb zUAj?bJ1J~[Aܑ@lB((CoPF@?A p6\=&ݢEDV2G0jC냴g i3 n)ۗxdsiԛ"5cz9T}Mf*j"X5@0r5aJAIˀ) o҂R9CсMvLS}' "FP`f$@t2J緿4$fSܞ=x3ai5Ktc 0<" ; ]yM8s ! DjH8m? 0`*fo -fKS1_޼ai@E|жo9Yr*][-per1X=S^ezK+❈' #Ts*-'U/&K;ukusGgDuUe*D^GMȱq}ڷyECZH !!*S۩¸8SQc<0lTg4x~ty[ XF#$.: `#a%wn3p41K|Mby1~([!޷0`!RQ!Â##HFPq04lZ2!Φjb8mbz [UKJ?h,歧5GNSb_̒䵦UِYlfi%AaգXXb@W%}lJ/E ( R4j[Rh֛a;n_U7ɔCmmsWW{[yPm$VzX]W2Yu L7a:鸦{+Lp$L@(*IGIJs$\6Ԫ{x~s 111GPǼTdq.#Ug.(:-ʜmweJy&t@9y'WO"ǒJp6r@nB!mVq`g/Y,_ ymuAqάHW2)[e\8YZ[2!TEs V3ttl@vڎE A Y *{FR5i=eҺCM̓[(8kjCsj@T!T<{eN t?z%7]<|| ץFIr..i34b֤\4uXCƩzJQ{ַI]J?*&Npn#0I_?֣A鼋@9d Ʒ:*]hbL;B+P5p"o꼠0/A>h YZ[>taE4"R&\ba>pJMfRu!6&Ӊ yIQDZJOSvU(C/p"tHB1] hYQ4!p]Y#k[7q?*0XE[Ѵ- CUT BZ1R*Ŭo8B$G*!s.T~݅3 G׏,WJ}DJ~ "GŎѢhV(Vwʧrʭ6{M5ppRu6/16p&|.(_m.<~rmb]~o?b;RdrY)m*@| ?%hYMƎ *!U`-Zjѵ:}N gm%Ez|)N-/QmkĀ+Rk90xlgf758><`2)ru^ZJ`*SP)c@Rc ) v!TTNYJ+[q(Q&`-.K9"W1M|EXb*fi΃74V˦@aKaW L5Ir# .6@F:b!cYz 25jkJ!sLwMWH* NCι9-_`4Uʒ-Y*@v4)wZl'H.:c4Z-:y軘o]$*yWlmj;-'4-S ab4TܽRr`M:l}mYu5 2pUFx6a[e <7lml?ܒdZT%rvBώ T#nbFb;A]Pؗ|/ZcK<Gitn(UߍR ^X6dڿ`v=WW`Ywp*]fg+^0Ir8),,甥`~ `ws"y;>&8kE/lq{ގO=F1$2 fveKg8tչErk;g Y]F MEwG,xl=k]N/zV' vrksMԮ] CL+fi^LU`%(pA=Mˇ-д"6ewL}B"wDTدf0BZ4 Ũ%||8<>~MrJW4>N \a]M"gr.E+ɺ@ 6&X0rJ';")h6bI,.Z^Un[!L;Y@ݭ-=zw)?4\),).Ԉb}`sNmWTÖj\yfʌh8$!Op}ty|ħ9NSXؐGvh@Yr .9-{:r+0.{z|߾~{~ R /)t\򲌣DP  j欆,P$<-m>0><>pϷ󒖲x(0.D-(RBdũ`_" }<izab9=%ڵLvpXOS:qqy,)"g7 V!d$h JAW$Rh.xΜ4,g^#-rmB%)2d|=Ӈ~x =Eבh3dYRyp9>tpx,<`m\Pm)ĀA0 $0=:o Pvc4Xc#/")FTB& лV }}$#:ؑqN5h&R%e\xZI^w V#Xrq8Kry/rmV[p׵*{@m1lD ~:}ߞ_^.ӘJCyuf~7>?~q8>0aG0c2 hK"1/q^׿Vp1Ih`:X\ 1...61]o7iڌc_jgY1Iq*Fpw>9 Dzd%W5 -GhYLMxRwu%ytpar[:Mb7]i9FI9/o\?}e\`7+r5JQb1+c#K`,_$EYy1:~x|ϒ&Y K1崼]g1L}wd໇]Y,r1>l#tl#Ԃb:l o@=28:ks c pBT6P@E˶zDeKX={kB+<ϥY9t:>t8ORιqxs Qsr[N8/20t8n΁%-wUQ) d18]$^\}xa: 2!g ?. @&qQ &X6ae|=OC yzL;G[k0[GM}ﮮP@@O!b2rINr,!IZЫ()aƠj٨E*sJ閣KI1L2LJO|6}m~qmd,]̤C.E- ^x+|9»V[C,5i1MdwJ 4O+h;hK8;XR"#rR8ǼH\|]/|Ybt8t/y/ZV'cyZ^An8?=<~H[]Gy'_At 9tn}^!3axʩ5/)f}YJ_CW0 'zB=Yi{= Z!fv IBV{u UWwJ{6KFbUygyZ5ՋXӁeI3LWkhs9g7J2/29@|Ï`-J )1_]۵<Ӈz/PIm=Z_N M_\bL]WM@ Wϙb.ء?z?XlZR ^v u5N raotVy+7B0l5VǪ?uUVgXMUV˨Ʊ-n@z3#V*C,!0Г)%qNzbtc BY-ck^VȐuh-ԣM,="$dَܹ*- *&;^rB D󾘈'TRb3]wp7dv?9ݹryIX޸/JHID&nyu'V6vVRIOyT@jYdEӝYiuXJ iR8EWAQ "㎇CFyBQ7DRJblK f\JlWeG]ډ@(0{kImq\㑪>kW^!pL׹rNFHkZGH\oEt$869J*Eۈ#i9kˋj1ֲ5[0ϨQjc*DŝCu(e !8geDzIPIauؤ&{@` K0^xӔml R_"idaGK2ժzv,ޙz ;ʋ pqƑ?^P-B'xx[e%j\BhqZT)/8 [NqX]pPA$VO}5jP²UQuKf᎞z_*,^3$٠9yccN\[-HEMX ə!,2]%\.y<+B-x֜S 5^r})1=S4 ]z U8_u Ft;R\00]o2׀ݝjXl՛P88*wM({XbHwRu;QmŵVIG2k&UT]] 9U3"Ib QFx"*ҷ'X%4ETwꍵ8qH"; XSL|7!,a$'W]VԫHrN3 9gݡ#O[zfXmN)ŤLleb2d@hSHiZ7< Zz@zw[]/QՑYKePZCy{U>w|pn<**Q)"`)xA;!gVѐI12|E36H+o9N!Mz$ksXr3-/[SD͕$WRAp5 G?s̜XK fфT0a4/YiU*YT۪V ]eww6݅Ո_a.n$c4aa@We}=.K!MKuȩ q-?vB\"snL^}Jj% \iIlH%WN9h?ˁMsDuބR\1Rij8֣dƶ<=٭6 kSr _(R|.̬ uѤZȇV H`:kBQ>W;*o+wO3;mZIG k%oڔqz{#JbwqIcΡ3GUO(5R1m aVd kZ4l =XhCc )G*;4RZ0 8aOC$5clh[9.r*_cYͮU.3NŰ{^=d~vVy k2񢉄x%^5t.0ڂ$T5A,2bZ6-D>- b\!* 7FQi& b4-Yq)xThf1\)9Hj^F+)+aܪ iN986_Y":l <Imj% 6!v{}y}{}n`ax{8NuTEy+zƔL6 0\3^hZB|hjskn$Q["m+98bܚ5vZ_ NbVkxy5k^'m v{"$!b;iDΉޠhA}Tќ1ktk2P`L%mA' )P"4KkJlj%4Gb#/hc׷2όzyϽJXNղH6U1'r^W98fMG+Il5Ypw%{!3kFE1k^x9XŶQƻˇ񮨢lM{g=vaݹZR%Wb;<cL6JZ*ji%Ic:3Kvm$?d,r.R*!-!N˷o_^IL92n_}/Y Z KMVLCD1[kX1UٯAX%a[~-4>R' ޘPĜ:JXXW MqtG&|?>ܹ;_P11gW[vyR: g;g} :y&M_.oS ^q-6Hl?peooo߾Ӥ\1<.4KKƫ vY=m51@ns4vњAp9jJd U_ԤDWtXgkVws;Lcֽ܃*Gx4@56ObyeLf4 ҥ[)Eg*G:!R5[ܺ~ә4.4攛\WMq>oo%(ORHnΘLaӢpR!EDwǮjnZa$_Ϩfkl5RZk[ұLax;PZ]zCQAxG,se%rN%4BXҍ:DZѐ)AZ%ޖ4+U6F*[%0z)U`?Đy9ippm8,iYS(jAAhO#ozfIjg]Y ʣd*ԡ pu1vuIK9[Mu*Z=؅D{o&Hһq7jېK GY)i@ լa*Q@%J:!M1:7R?kT20st9eM}׋6﫯v; 0\ԉ9S^$ea JJ6T  d'w~cVuk0'1Ւ;nŮRەmm=\VV񯖱ihmM$?+n y}(̳dPyƕltlm n;8dLW* r\Q2 hS' C~LU$8bIVxW}V:p^Sg@c'o\1Xcw܄8M4*j=HBkǨ!0:]*UC.tD%R2$5i&+8i$ӊRc>NBDu%Io\]R.2`vGGsIPq^k.9T/!KL9 m=%+clp@HJeAۧGm,|!kn-:띓FË9~X;Yfj˖!`m68FpUHmF{0|TsP|"ROQZh_tF{dΦ}m:! ikUz5uQ1fPOyT[֞hhVyk]?P"ֹcA-YgY%Tw17Pz,&Bp:дfd * Sh|qO*Z̮滱˺#ؤw\u5TM^Pڕ=cU*!ZeAa:c*AJɘȭz-H^ڵ#h,9Qȡ`JD1ӛtp'ԞTTh2I9`;+פUXG@"k;ԖBUy78)|/o=?9wIbN} =Gz=<@@%o_G;$i AJM+څn?l*6固e_ ݚj'(8=ǔ (+l2L.U}Aam:^h&ŹҢ_ N f`Y&J6"ٲYޞT,1K=:jC9 FCd搗koׯsB8XZ@px#%Gh: r[7v {Nצբv `a6ʹ1ʝ:&SCc*_H8X}6OU=GUDӖʚȴ;YL[S%lFZX #X:rn1uy֙ nuHR{D8dP5{2*[]@ Jd爕1s̑üLqzM k`Y8 he{28P]x;ɠXY۲7߿{ײCYꘕ>D;UЊ #ER KuZfXFdĨqp/Un:Gj*M&ij֑U  @X.|U+۫jmpMERD-+H% fd@n-[S)=b.JyFG%ؒɭb-H^`=9.1CJ$Dcdd$Y\[<_ӥ]G=9cV<]xZa-<WSug.?O|==ߺogsBl}EﹺPJpZI6bMv# `lg;s S3Ik.ܡwj$|ޮt$FsN:V+ 7r-TEU8gI3Ui檯nWD>>Z4Hh@,yR8ÀYAd2ۗW>uተEb^+g~?|}}w?5E=>V4*Ej'8[!lTv[:A5Bi@L4"L1]dC"=-ġD:sufqIl'T7ifgƕzMit(7xs \cv,+].W6*6&C!7 xM@g%8^!m"!q;)/;>b \\_?yh!3~gs}_}R]9QjM/wݵU2֘fCVV6g֤"'qv5MnnP(8I @9肜IgrbU-1?>X$=8,B]/5,甖>m#wn Η˯RĆX+׾j7C*SeH:oJԭyu1O"ɸ!Q$!aĎ짹Hx< y8xyo~cA :C Q,\ycΞUy ֲ)k+h WuOV 6])"|IiVr*1un AGXV.uz)>GL41} z=__%@E𭵮ֻ19uhBKEǤ3\T uFN Rlڝ:6*&/);;2r8 !2 t&//{ ?#t=\o-]/'8$=ljb$JHVr"^3\d+6G#sffGjM@Ť'#.沖txhI%,b.`C"Fls[TYȖg1S<>7 t8=?}moz] YCҚZp݆ht\y} A}ɶbiY}y]lnmk6ϭHW)M@&:sD"'Pf㌜ O_{:8˗L )HZr %~5EZ!Ӓ r}(n &5oĿ1&jW Y MVrc,1hP0<̆8%&Z;t'U!R͂{aSƔ s=őŒ|GL[z8^_׷gSusn50Mugkһ?\ǥ,6(k峲]u+Yx!k7MN"+=dD{-n4%% H?X/3?.en,I,MJDX,#꣸ }j6ޒ|`oõ2{F2l}k6*ѝ5L2Bc^8/.OI$Zdٛ:D:3\0(yyI>XUTuOoM4r-]EQ8d.3@mPw /WIjە)^!'UPgn6ј3mZdK*tVIN#!I;#^Ϸ?#t[~Sxt#|Co}_բŧRR0? 1l6'V:aLMI399Al_ݾ^s 1TG \K+3ڷSяǮIY()6U0b/ı8 1כY@`a44sZ `sΚPy5uF_Y /U>ݦ6|amaJq*a)Qt3=ӫ/i<~zC?;= ) ! ƙG v-rn_a'Kh;TRZ29ǹlXw5D+>ߍo#Yq(GCp/AY WqMtlvc1c$Лo}荊AFdR:χ&ͲLIoq]{k0ˀ?}?6א<Ϲjw:]Nquh-Z f+ I6}lYG-iLb%U%ȕ_%g{7; @p7a"~sxx\3']_ap:/LE0_;NrZ|U}i*\ZJnl{şCv09p`6PʰNk /KIԦL8V=CI7N/Cit9S,Tw H ç7xysֽ J#N5yMEC4?jqu-t c^y(k|O.9uJCY AkFBl:(1Kz{ k/uv'U"1ŜR hصkIPǒv on^|ZҚ$VylXN#?\Ο/oإl 퐿SYkџ}aӭf>t Sp:t'Dj" v>L8 mE+)% )Yw:¨OYExL,a^.yed^.{Ǩi dS*t`h]*gW NmTk+r)2dHb0|}|8x?1孛lvRo2]CoLʕi^juˊD!:P tJ#2aFO)1,uv !`KMUJ*4`j$d6DMḚ$ 5%adP˔ NaSؿi<0%b-IKSo]?g蘐ήY|)wLQiCV򞝩np>}}~NGcqy [gnrIUƌ֓p'I'Lz>ZqMRTڨz$0,ݙo69bU@:Fۯ96}n.:b3[9e- fƵ]z#\2-9})6dBZə"Myj5!ҠCӞNf$w}l<*h9):ZCޢvolC/rщ~?GaC؇Ai^./_SsY&?lª LAQAZ)) u> C^yjU|hF=铵t0\  Lm<2F0ccBguc%TwnTfFUzFٶ:n_mmЬ.[RAGx? r-эDd>p}NI Gya ^/{2__p} oKuІT >,jb۵Y`t.C#Eܩ1w3ьnXRc5g͉tP1ةLN[nUy4r8s|!z6 1&]G`-Hs_0~alswu/Mw_)j*\Y&`6zI `qbZ?҉RyU6-tHegHCvH5A9ym֒)Z֨I3%ǫ;oƾ rL [ނ1:ϝ? }]pXsƙ4rSIwX`mvPNYcfvNDbJ%<=2۷UrĘH<9H4/RB|ayTץ` mב+UwAcH)^w[6e%Xa!o4N],2[ztB(7-*sggSݎȱUER잙svvlo[ɪ̌ |DD=:e[HDYo ኟW;#`W7MXJ2 U 2l9'tX-[qJH*Z 1:wz{9=as8>`n.тb9pJZ2;!Vp y#@,Ε 02g;(ͮ;wۿF|!߿R!!71![\!OqTS*֥\|#VH+}_d|8{`+PgkX+Eq)i?ϴ[ۀUܮ(20") _J*Wup$e otp>nܮ&Ԛ~aQCK8SFw&ڒf+|\N*8j+̥޾q4 zqWkQ~޷j,V 絜1B(-l tQ*Z>HT²/粜|*ٮ:U6AOkQu; JM9yr%yNy:uҎ9Fk\7ڕ^B!r\;blݚ]=^_?oPd-NQJlxPksJWR@!!:Hsئu^5]ơE dEeLy=8cָ^aGyҞ8WJ U cÚzckmt2KK3a)>Ʀmj??=%iVe|` _/R%,)ļn1/?{euo{ZV SU̩e2(O6Ek[ӧ۵R_J90>Z(HY$G ^kNй-@(5Boo{y}?=s(R˗H޶'B??~y"_j=A$Zcl}i%.yv)R&Ll{^Q\v[.% NF:O?+P6K_ zʾ@(r;`\3-׋[|`u>Ծ"Ex-aSr0.Q>ôLi9Ƈ{O\n4 PcxSUd)e|8=,Ju uՋS{B͜CARnҮq,۾ltAӲ@̕ҡ\,I}]ޒH!6JSbx-E>g/ŷ˰Ô]t=)2ʂp |Ǐ|C /'w#gzjFkJlfzo8QTJ( @Vܾ܌{~cOYBp9UB 2k!/3fS]%XZQyU亄lyy݂X$H'=P+NBu` L*OؖQ3lX"R ;t&j3tFђ^xȄ3'CIˑQ+'0l!]9V:0ӯ{_OF6A9DG*fJDp Le)Rk-j)²nmlq]C"M1KBh#/ZdCX6Zq9ԎK\33dbsZqN8 @ >gDSL}c[L ;-ٰ.4Q%;^ξ7w|.dkxT]ⵆ  }炧9r vPdž~C~ԫq@3A3z CưްhܩJ؜M1?~= Ȣ6.p poo/o_^__.E$sJ%qkXb\ma²*AƊXDXZR qa:Js&ܬL]bڼzzxT UZTBwTc^9guR@;G$\hM#waE!~[~^y3^;׾PKAfrFYT yep ?- ӵTʕ / 1,`uŕj aחo߾}uPӼl.=-^znVȸAgdE1knV=[XtjTj EzЙ*I(F]9 H횆(Rϳqe<?B5gUh2熸]{0N_n%GJg;h^)h^XI?w+-+3Aݥ04"RL)g-!+lnR8(nۗo|{$s ?Ѫ-l嶼n/J:CKZKJ 5[E"R,zG $o*,vMC ]g&QBzTg4&S* COz7- ♣"d=Dض9LW9 e_W@- @2;MgN"k2$mWJ~'.vib;^XdόƃicXn"/1,߾|˷7$ӟ3ɪR]+s@Vd2FK\c9b^$SR`j5 (Z1Rͬ}H%0=dom[4؃#A ho  Ǻ.r [.%TM=Y$ޕ6Fq#ϗ.?lUk*| w0Phi_bEc "e˗벆%ƕAPp!3#r瑎#q bTqiJ%i=h 2*`!kJj>ضGXBr)8'(+Y++>v3oX? }%p\R&-BqETJE{u/ݫI=Tcz19*O-; rOH`Fn#] BaTMq<" gxJ,BGNKի/3J rYEtl.K6aST6No#@J!գ L>^SP͖2£&{b%zKM1TYA$^~ 1mT2L[ih^krpj4ߞ pש=gX T1gDWc^oˍ’սE9Oaxk8FZ^./Dx.˶\UDdդR2vURūYc7IA`@4{c =#)W)W1cN)2*Ժ^լUcTCxpJA}e"j٥u)ٯUVJTd^sk]NW+G| LNELΡX* 效D)M͑\nC+fYbl0 iIH4*+D(*'ЖX}KND_oh7.*Rt9O^"4'Sg3/fePԸWfQBxgǾ?vHdY ƬGEz~<܃hqt䜘!u5S=> ;0i%F qsuf]HMσ'|) S\K6K$:̎qs(9zýJFq CI\dY@֦8Βc?3ʩ}en- Z=?rJ{%奖T8РL|j ~dB*%Z6`@WOY_>2Nԛj2eq̰9Ъ`0hinj7%[T+S$˓b.Ph=T!7urUaq[cVg<$ex]&A df֐y,̮ *+bT RSwH>0P;@o Ӑs:}flws rZv^]XXL0*h{q:k]vs|\("b cIQBJǡJ>Kyut8OhV2\'k*q Ty>qۙ*fS8oVq*W,f~P'|u;\2qQӎ-<ǒ鳯ēU.Hc`ϛ/c-&Lv"/@v<Uu& ~XqE[].)c4ik #(&ܴm!Nqd`IZ3E &ҺSRW#|-PUZAٖ`T@h ȣ0HeԻ!I~,)&J`CI% 2&T -QC){ɐzv V|9P*vg. tuK>7,p v<2n4].vH3#VS38-m/3+wGݝE*rX"/XR BsUs$MHiE_Jn ҰGT&6x܏kd17do=T{ZazF$sdh,hvq-(JIXr)q v]Ł.26 aihSH{*﵎;3bKz{}}ykъ]xE9gPP(J3#>y/q%\x Rk׏QulD/uCB\F1 2٪-(?Pĭ]uz"%xEᲓl9 z H)%VQ9wl YIh^ =[E3[ޒ#UW6gVKXr>CW!~(_Zx3 w]u&:(3K5Cp&F3hDi "J'^0QMi JwIci!58d.Q-hf`޶:"UlT*EB XSctnޖ`/닛ܬO.\r˺ւa0öyĬD8wc_Nw ,tĴ`r2n1 ,P|έ& BNnwraE Z3mL>$kd\B1`P 5^{U3z(0ŀ\$*ŠDwNLq"t(pS~CD'?ĉo/Vj1ڎgvh߂n&3s8>?#&Ly #x^MIa/1*BbEYLnXm!f CĊrSvld,KBůŠ=R.NJBoAd辅q=ߠ罉-O>$%"_mQ!c&=, E=j\~yzJ|%F!=sJNHu+r+8tU"g__|i[q)ϴi XE~)BBʕ:PZוeI\dK')beġ|D9A P\*&EIFpP6աEKlmUi'sєyJG+hǔ{-=i2Y'ղUZ8*(tGr2_{f>纃G<Ol"[82%H|}_۳??g}CiYӹz[BhuI5n׼0*9 :#FV C$J .aW$x{Y-i v(dq,{MD0 ({#@. &J䡊)3YXD? }_-oAV#G:i&W/#OlECc=z'~-1PM?>_{>eɇ}`r8YWk$*T!Q?BPBDA$E R¨ 9.D1&䬚>iSR7#"uWͷ(:nBV㫲6ʿgD,tk^K=ьjI@V{0k>UP^XJ6hOf=+ޔvtvOa1\{:^/۶T~xlؑ-1:MX]\8ceiղmEORwz r健Vr3tD59;/ 4Pܻ׍]?nU}KG!oj ؠO׭Os} " m*&; >V&Cm^|{ R9_fC aUW#>LsLY}ܡV^qo5qTyzz.MHs*\q. ]nB'(j꘳&ʎBkeKOE/4mTNԾ1?뼋XUds&VΔ FN,ۢ:EEۿG犦K9Rob,Ȥug,/1"_6|F'x?rYs-~?ϳd UVpKxZV`UKS@1Q7Z!-alk;V5 죵*Ѳmqg (\qztsR0j ǖ.tejaFPcZ j>JtٸE|Lr%B[?[}R6HU5_?;31VDZsRͧ&&z&#}A2 lrD1JT--8tHW+TBqQe(FC.-O6>$ٲzJb ml)-ɒ(&PW"0$,,KNK ovNmd7\#0L"8G ύDoC~O!E%ș?DT!x`uGVBT $)Xg%*Ip&\5T!HaH1ׂ^ˊ Q7ӶLNŠj( F͉wGlk" ;C l: vS ,KmYHӒv6?QHS%IW<LC;L)+Q.H9A-*z.&9Yr5Q!ӹI^V KJ;"URIA'-+R5#IN ]e 8S<2<3[sr=h&K`ؑ`_!ڨK/}d \Xe/!WPϪr('.h>RvpGojKM[ gDc་ʙqhu yA˶5U`#]n _IzȠQ(Nd /ƧBhSO!;= ?Yg)]"g%x5bTQޣ5kZ!C"TIu#zphiLO^{k3v>15z]FQʫL :qfPnhq.aU6AUDLtV'q *U*g\`*y-%-g krdv[Y *=-ѓUY:`igy r-A$yd=8F̪t>>9&:Iq<@mWX!lNPT 1 w:>Kۺ\ geG(~&5^9m;yr>ԥ^ԥ?M! w7X 0 @9(:^?;#V5P Kf(io58[o]qT; cPOnY֖hqFo|Ik+sjqQ{ S X1 UR^m K;&0d*TS~[J"z1Z>8$|8⪪h65Κ4N9u{aw2Zz9ڳdDcI$ƙҏ- +FRX(R(Tg,rgNG:sI.0q;$>E6ع=ؑ֋F$&,ҵ2BU؁dD[lZTR)Bc չӆF7;?++P^RX䃧@Lb+M/-rvs܂CΔ/.ȢK~Dwn*1p52V81+cWbPL+=B'*äAh@XG:}$C:&(hg;~~ \,!ւG>Ν]$h\c(aMA]Vt٘) UU:uFbL'3m-SBBwsm?a$Y+0(i9<Ϥ?Yڙ=Wcޏ!!hpPB3py`Wl!;FCdjI 64BC7͏]ʢU/Mj(EDw˿ XWy<2*k٢BJ^t g}4#~wHyLE$d`(S805'qA~cf}ۺ6߱5] -o0FD6/;? ;!Ô:Wyh3LS뙧"v{ DԈJFz)k+\Cj'.To@7ٷۧ:CPPVWJFڵ$h+'0%ɜұ/#CgN c<]|s- Ӧ$imu<ǧ+!8c?c`|3mvFbsiy-]iF߈įU4XhI=>@1oI=ɢ Ʋ9M}@t2x)1=&$#2pno ,=])Hq++=Oud>i3 0vm9~^h`YJAxb ADR%,g ^ }e,85DN* I2+gp|NpDM9;"Às^m;Keʡqy/s$Nޏo o|q#%IENDB`gift-0.2.0/testdata/dst_grayscale.png000066400000000000000000000425771513354670200176320ustar00rootroot00000000000000PNG  IHDRxԅOEFIDATx|}Y\uu 湺z$%RDGvlP @$p-0yC#q AHB3knݚ>Wkiiwfw 77+ E"p8zB:P(}ߟNx:gDVZV%h4/#H<bx^x/~f۷WճgϞ>}:Nqr]Vp8/ht^2]?d>zN&ŢhUn_*.|۷? E$V;;;^wdǷ`WU.|Ng\V[n?r=&I8^,K RT,Rc0>?{DX,d>h4Zس|>f;ׯH$\.\Vn _oVʍ҈,~_⿙+NS!XrXx7?7'_TvU&2rY(j j?yZjZl,[[[c|Y{w_~n\t:wwhzիW}Gx|>cq"qt:L&D"NcAV|>HDW}Z^7t:ttNd2R{x74K-`3%bjJz|>Njji-hU&pÿ|XJ Nnd2h?͖W(rP5vz=ݺu+/ + (JohϰVk2R)fԊX,X, 4TWƐil<ftZy^ JT*N|^nM%]`|l@4/#7Lnoorh46wAșHGe_\A7Ͳl*Z.N}Q~JBDvZ=<cWBPiZAzxZ\]V+& qMrL&l>d2ժn7M|"8 ի\.W.SΎ\X,FEƋ|X,s\|}~*yL&b1ákb .|Bu.0tɗ_~ D$ӧOzKx<P.?۷o<==PtbLH$R|>h4` {{{;;;x<`Z[|>on7L Jryy WR k2`)cX"H& $\p sLȣrNjb.f~&D7{IYp"8 C\Ӣ?\ɝ;wJNa 2N.no'b=}ǏONNd2bx; Ku.RBd^|y||X,L&drU*ZNC\L.&!rfp8l6L& tFS;ir}%I$d"v}A8(fKh! W"٠45tؕ_VWc$ϟP`p3ޫVzjᮠDy^X<88O?3\.fx\M9l],Bp8J2LT&<σ M&Xlp 5_z5LJR2<:::99D"T*' ,W"fiFX5H [%W-$u9zeY&Itb]>^j'4QZeXrrrppP*jZǸj:Fy=~vv_ P(DWiJF#hZ &N+X_|=KayP|;==*GGGDRwU `#$n(Uj3ъylP(Rx\.[>V%XʊnHJ)+X=S wܩT*v[\V`:M'OC2t OyA("d讨FhhZf3rrLeg}(<[*=C"5R6(DVzn///AmF@JF}<~I;ёs4Unz^Հ-a& &]<$@t:R5P{  k@fY0"^2lrVckp`0EX,茀j^l|>}-J%t: VZE}h4Z(r&FlV*rD\h.9WƀMRF*3!@UNE{QV{^ rggˮ DT"JRŢl6z2A' JS8]Pp\?6(5"y7+X,D,loo>yل ~Qz6@C,|{2,l6ý=<5ꪨ( 5Q/ΨD94xa lDݮj|\.O&$5-,8RR//^XVfSP RrqhYdA]jX}750*۬vXq[^y.{w+ WŪsp:Fx 2I@/46a"R|#~55DCH[,+ F|w҂? 4/3Oˇ'NZ UT7,;hA!ѥ)."$E>裏P˝F^STZM& iy2i63t仡wX\.W*dSf\d,^p);||>;Qj"t:j(hܹ;dbNaEPNCˡ2#d2AVSX.DT*mV Zx< *$bPQL7&IDR7NXLP 92zBPqïFr)ʰF_ D 1X} S\ 8d`e`))>E^VXE7BA.㣣JV'Ҳjr{{z<f1)FyX,'`\2>zF#LlBPW("x&R,֩DUiE*zZ `Ftg/KH*8h02Sj48H7Vf9Lfŝ@Oo1㱧 `) O>Q蚂\E&)OgA,4#Y=r*S/&AB V۠iz4f!|>r)sH1D[<#ݰu2SRj"ݵP+T2LN~ѣ|>_T7i>,4HZr9|x.ݽl4H|6u:^wqq<q>5P/VN k P+v:htΝ{Z-$FQ2FL&LxCu@' EqI3YxSA2j%hE-u^ BAvܽ{&L]#dYR\. l6 æSs\~F %BѝmjJ{vv|c(FAt݋gBnˀQ\/ւeOQg+O4nL %_ UT򆣣#D0(-cWvbׯgak%p( A(%l>D!\>HSVGK3^}[})Z6Iv8x \@h *|SjgϞ(PP"%r_pA? Ј,$1K9u. > ‘H$NNN)Rj5piv#jkHb3rmL>ȇ"S#,%COB |/%b3:-2JM8@rF~hsr`c@3d*4jV￯\aUl Pf{F܈ \h4bg&_4an yMi=Y!RьP0uj`J&UC0_4"-39J᯳,Jݽ{w6:c}!o0 )JBXJ<@fHD΃bFQP,=0,W,!L(Hՠ 1h} PV"L/\4T̖q5D 5JJ{Д1/ogpf,D" > ͨ5@0ФJI꿰lN-ԫ*Ӱ7_ʲ5nHAJt'?>"NZfy}G KQpP(N}_dȓ0E>s(l' }xٟ8˗vf5F:J`PI@*ڵ@[=zjmpiZ3^.uJ Ġ#鰩 Ũ\.` QlAZ-[?Vy~+d2|9n|t:;Bb.ZEb2\Dn2VzXAP*t:eB%6j fLi]1Rřlp1qxp:K^@BA'?]9d2GA:_/~ طVŋ^t: `4 qv/hijrFmw=2A\YXF[6zЌ/4Wfuo{1X,D@B)F7?eD)  "L,cM&驛@7Ǡ_~}uu%Lv|< &m]`lx`odixÊ, jh%J+0Kk*9,h3iVRM`ShGXB5aȄ `dS{$?5z}lFXD|  uTTFdC7RL3NCW_\dg٤řgJ֭0&za>R).$}X߅.vtD1|> \D:&n-N z=)zmZLFՎuNWMh1hc#%e5E UbWCf^o'sFrA1B[ ln~|>a1 )uAZj5h?Au]r.+ hYم2pe۸{ov2Lݬ:q-Ք#SQǠ0yܭ%GN_?!WvckahBDF7N9Υ^þ!~PSy-7bdH_[M2*p7t:m48!pcAZz]j"k D1ŭE5Ҳaj…h~kD]c7l1I9Xĵ:h|cȆNBaϓso)~j65/^ ՛N!lV,ht:pVmF G-]Tz9Dr+uix1ɂ7b/\@U=1&P( r0]n7H^ ol48eͨႀcUJܳBx<{b(ġcsۜ47JpL2h!ɷBØ^2L"9X~BÍc @3l5M AKxU? ɕD6@كϋZK ze2FB Q'gkk˭~~_RluLbLV{)fV@j-! R3a``dfNST gR-PLVU"p+9Ve~J]c\ J檅Bnj !H e+,+ xp̷T_}=4ћn =߃|UŽz0PBFuBkrK3|&h!bh 0pΥoTB < *+vBl( LHƱ ҏ 0Mf!%l#$PQɑ+c6* oH-MǶ3Dtt:!inh(slL\wKQIcs2ZBL/G?R\?~}i%s@_hf4t:f2YW HmyџɟʟxŢj]uεW_L@Nk37ĢU8ODeO)yB1DH///vXAN.H '(fe4m-OQ dN F̷piNvՙBLA*a*Y+@[2 -W//..Td|"pQf5&lf0 HU57Ae xe8h?U*gϞ\A~MPc*ϓXVi.1 F #Xn p9\'،Ӕfyxx0p/Xԇ70{0h\ R4d2*Fuj)y#N$0k<?{}rw!ŋd2 MhFkr2kl934LM΃Si6aT&#v.#(YkU"uxJNL& bgi¾|Olz>4pe<G!OL)_Bp8FcwwwkkƼ ?c^ Mtz4z |ŰH$׳C)U>EŅ=xL7~`N7O[<:.Ke-\.u%B?iRp+Tp8Et:xtھx|>%l=!+PM`B)fṺ w%c8ȇBpX.!s=h޽{Zm<us(P:;;.፩XPBPsM0ETMJzX~hx̞zϜl'UzE3O`sI̳Irzbj>8 ? }1Ɖ4 o۟Je0`gONN@n,^8Hҏb/볳3 6PqvqVfWWWGGG*L1ys<7Bj"H\/~{՗_~n1'x8c N*8TM)S9N{{{\V)10!*e]zO?m^g2ϟmZ$h&89uBuCm<o Ë (=99z9 7oM5RUmѣO"vuyZ|n," qzzJgX+SmᅬNt '&L&(#C(JgggxSSjMVH`Ύ9.îM`a)sxjB!Lhs/]>O\^yj 5zUE@NS63[uL4⍂zy-R`Q!pO$uz_qN_湓 7|s'jIb`}nRnYf`xiz0qstJm5v8:ӕ5@>G% CV#,|HSxOMvb R)œ'`>Z4 i|>^7/_yMr^W\,~! -XKPv*{y}s9~R% Y쎀g*, (n߇抛v mp:<>|XSwvv&nBt`PENҍxڰgoCUVtSb:VCڢIc9}LD"wލFlD(BPP k `W[(TA6]N RĠZ[UEh4T*x> >{ǃ>UhLuXB(ɤkꄁ6(Qr茀@t#Ykx`}[e^9JAZlAAo:\gA 0zJcad2Z@{ dwI**˻^...pp"VmJ(Fu dM<DGvb04 |BTB l6II$W_r9OAP0&j\)C2%JlE,2+f<M0= ; |S Mba Z%ՄHFS֤:,enz Rq[0hHG˗{H$^|ӟ4~bXyprPj.mAЃj^:F}-5A[<]%5&ex^VrLYWcS/eBS0{7F@W_}#n᪠<:0gYfPBKiZ~ZJRgDiෛ#@iȊC3>3)z]zBFa8*=ѓ3ݳ5i + ;Yn鲻6~4+8tu:-akMC=~@vL)XWd&qUX 9]Ay#iF ]UO XH[rMFj0t#2Y6qdSt"6<<[Đ26>ԆhXMUJst4$ju"1Z8ÜF58z?A|It:}vvD5T,TA2lFc* d]k8ng}ړIX09MuݻfU*=ζf OGRۮuManv h.97SHfIS=LSr L= 6*Qc`9H^Hz,@Q  kzDӶʟg_~>-ʇ!gRB,}~nW%lLϦ0Q MW0oӌG* Q KuJZ8 7kʊ)v5+&(g Т\GO aHQtE12S]90ބJrm sfzt8yNGGj/ӉgQbR @fl̕epQf2zZt:6hLf$kQ}9zPF&Rܓp ]ހue M:]+ߎD\."L6 ]N O>Pv# 1|};{A}ת)'[Һ,C2PZ  2 2 p$GDž^^|~PeL)J f'UǵX=b0W믿>>>nZ,1A$!x{fE8 nUC7 fLVG`l>#ưǕ5>ik6l&0y:Fi :ZҰ@GI^Ã3FۆPsD0\ci}tMR_r4+ 8Q$ ccdh Nd.6#J9e"qU6*_G.K.JrNfkln[7q^Ajy8N.Q@"@Ef:t&!U^B.BF9!7p m40@M)0sj͐fϚJ50L !P+9 QDzuo˿k=~/J οxo=)8&R |籇K w9Ja:m 5( IXʡaL3r)MwtPNCP J03H pA F޳QnӰ,!,TX,mȫ2"!t(›7+@1Y^}YyԸ0`i$u0 [8iXH.I&8X͌(X&B8nHӛR49 .c)R,ܨ@8Y*aPvETf\f? ; K:HNtUKI3Ngɓ1Hh A| '֨Aa0,ҏN߲l) jDCKawI6Tdi60d`Δg0_jFFhvj3P`6̯J!icsʂ&>E)&D.=m)ry9ʚ4#GgXfpKE3v.B BAR0`Q4 E7n/pl*~/K4>S"?HSd3|N&o2̃6c$D#޷7aB.ʦ 9p~P2Tصc^|9KJbqm 4"%b h*_05 T`Z hYΔ>kҡm:R?"Q@X RpsevadhZfĪ L+ z1VmZgƕA[&ӞL)P_d\b\n::m pѼ9WU?A7ް;PoKbSy7N5 Ua؂J\FOB@Lk7:ng,BCD#>R44j>&@/幸2vB/kuoCzb >&iF~(;`l0z+jS?Hr9 ڢPtRn]Ej[v7fa9Cg`0@2Q yҊ,c (OG ZP/1JlCUJ< kS4VuU ӆ[ń0|\sW.KO耫h4B!]Wq($*9ǁ1R3_^*%䞩-PUVJݖ _$~AƝRE_aj "?5!-M$":qrC=ZRh4 c7d˭BP2a.4BoEAחX0*hZtJ@?"ǘ в*zo7a҆uG6ȔlQ@xpr Lp@CwtrCUv p8LR^=Ŵ[UZhhM1 EiKY%SGl@IIDK2SPM>6?/5>tpSqO I^H ƍٴܓ.<;99k̿Ȣ)#5 elг,)i%KA9%zbӢiu-ǡܻ@"Pxgx0 T5 ^FYaΝ)qr}Tۣ:RJ5ZCuT̾STkN*# rsjS 2`J; e"*LGesL-1ȨĞ S"6ek2NWd0͂J4@`FjZT #%4nrWMOu"CNMM1XϤԆqAtU4 XO&1,GBSPa vEfjxf j6&F, K '?hZɂ..3#ЈИ f9ם+bBenlʜэVȑU`xSUzѣ8V3Mr,Ke<$6O8F6Ȼaّ1nt [LB-uFT0DGOքn6r̊{ hT6Q2TtH8`.~2t]$ Aq++fPJǰG45hŶ)bgμV V]  gfk*GzYOvu*74G?ӫi`|*octbvxTrX*):` Hpu8 "F,/J *>$hԼ31TSs 9Ҙ x_ʦ G3RE!P.&cC%=װ[M8!?"UKSfze&C(RZj6aL&54G WX9ɧZ|-gg~o5m Y'n U.ͻb1B\Ԙ^ **k1Zl];9HeCq*gˏ t&M[a0l[ύ:I‘7gbu%FzLhkOᕳ٬X,N+ bX.kP1TD&eş*d Ā 2x1GSm\Z0ϸ&:~=Ol#7+*TK<ct|g"Rr8_UiE)Ms|1 {S骮5bɋz\JswhLJC(nk&oЎrC-0EkUc P7ۤUX5?VܞAqkL!r:F+8cpVqׁ-j0IӨ:?af ۀ'^,JoJ R8W^ƌ0(ޤzl.rǧ٠dЛ•<#7ITf9IHϑQЀfJSj&%{޼W7R[.#̕U~NfyDC`1<@kHu&_K"B:@`{9Fu2@h#Zw9-eKS` ?O0E /2uoj2Ӯd=L&H5fSlzMM6\u'Zl˘C}^s10T._d(kN j-ֽSnB C&'I ~-15Dp?j#!, ST2`S <*B]J[m,WS2qĹ&NMЕ~ĕ00y6RSFO'_ 6z?FIENDB`gift-0.2.0/testdata/dst_hue_rotate.png000066400000000000000000001056271513354670200200130ustar00rootroot00000000000000PNG  IHDRxԅOIDATxDٓ%YrY"⮹gm]Lg 6.` B" ьFe҃LB >LD"a(`YrϻrANMWVU'矟_d8K&DF`˘ۡk-[CD9a漍ez` lX,`&"J Sb1pF0ޒ}u5 Ddן>|bOpySF@!F 9["k1'LfȘ !93!$o|3 gU]Sos{_99~pqwgfF?{?~.`{7?z??!Ez{^wvm. 11sf_W-\W='̏o~y|ӟ9{6 >9"rLS77ٙE )%D)Fvj>.vyH=Zby0g^<] $ c,0cf 9y_U!;3|' CH| Y#XB[wO'~bɴk[cpRW)!$b`QNr,WMd "ԨerU03$.|!8 91#:Hd(]WkWr7'߽89?{oU3飣n/5m~g[~2uM{ $:?"ʒ0?#~/;_qcLd{]Մ<<8@]m9PDF@Ʀ<{&\w\o/WMޚ>Wj_L=ty~k[yЙAw R!C_G91ece;$ eōAYg31hɖG3j_߭nzŝs( 9I =!Wo2|$-dP>F5,ա$8 Ԓu8Т+D^ӀHl]s=tq*~Y32ʒ#璍Wj;?BsN={.ɿgwFW$~7.6՗W_\\m](O)˪4}c;SE 1dTuV!0䔣.w l-'˙_L_캐2kC1ȑSpŨ1 G$5I^!@GT:c,V^D!(:ctaNLiNl* c yy$1`qV XB) AK1##4| rD㇤6GӓB4vuys46 YU?yLYB#(tvt~Go_yɎ7#/__|lm9NVRRQD] JYzf<8xprdxsFCB''GGrJHXR6rBLIRH$&BIbA e 뮔.qF*"и1d$ wdάwz#*UΔB$a4ZHbKv?FAMK*87/HL3VSƕ K$N! տ\<ڊ0ܭ׃<0$o}[o\I ([ y۬~ί=Τ:?_5GI{`{kۭw7v`-pWu5 rlHŚhe mM4MU5ָz;9}MM-\*^jViNn_}}xoRM?y偍A\[)R8Ɓ9M]sg},I3AA,F`sloYYM٭,dz;wwZ4|d-7 "dFʛp YT ) + A}J$ FM )K.t;Dw=뛛W,Y\],0R@77&GG'zqK9Xq-vHm\]G8 1u Floܴ.&\XXV g 9)`R"3h)FǑ4~ ( H#6YCR$t3obvB.Rރ˻V2C6sVc̙`g)κ0H޹?ǿ7?~luۈi UdI`"aj.P;ZΎʃßɛdy2lF?~чߙ43Y̦v1 nNܮo|b3?ʃ_]Swi,b ]cO8?p/ӰT?+ۉ5]e;gĜ{+-ھ"th5Gg;Dk'OڜR>|;'Ϧ䘺%M31l1|mhѼ~ɇ?8ޢa13$t]l&{-HdT Y_m̩|"K%D,gz7ߟ/f]vC3F1"KʎZ ISΒ,}hZ;gJR-rtFVd!WCI6 g@Iɭ I"K$g_|mmKщ=pz,`._}v  AҷeSF_B'b%C7mKG,XOlUgaΧa )%CbINi]e}!l~t-l\f2f9g8eߤ!N|qXnYԮHXԋŢ~̚v!*Xb`荫;/GYa݅M8RZ.VK2 Ae?~lMiX"ftpƔK,MIj)q J8K%(&mͣ]^]w1ƔN{bsSrAVwsϾ6\t|x-`Q܄o*ɟ_ )$!Y~!KnΆcJv6Y0Vrne$d=XŴ]wxj!;2e9b2AEcҬ1n~4b\ Ja+Â,A!53ݽ6-B5 #;L3ZRIM"z'h ҒjxBgTUdrTuJY$9xurwڶowton5Q)kѳUxd2v>v\'c跥dMT} Isd0 PXv1`WmHXej_&dwi`lcC4zFnv<9nܦy:_osګ/ q+5))8߀٭k6Lꦞ,3c)"e&rZ" ݯ9u+dfkϪŜ׷CRp%1HK|<e!#x!ܚ3&B2a,V O)T*sHSkq*GBE9)GS)emn߾z.ĸ_:}xJ(;3nO{pL7iۋ/%eOU 4KXg#ɪQ HB%+k$ɮ6mO䔛Ix]橜O ü1 iպ7!l)1cL62[f  C *AǠ0-[y77^ۣ㧜`{+2%Q"G@I\ޢER2' @S6Z+ DWDft|Xc3^ ȑQm , e2)|v}v|-]ߵ}Aa1C#I{tvΡ_Tsg'ÛA)'ZWR*x@]b%eKZHX=<~<ҐRSYSgHq< ڍkbrfUASjIq6'=3j_$۳|||uECUUj6d%,uc-6OYQR,eCֳl a& PJ .+tW IyR 8oޒ O$C ZRCBR/>ãnBͮrr.jJG>lVVAY%??o]\oW;rcXs+$u)0(9O"f ^p3hђ(.R5ƃ,4 )%lOLn1ui`M1a,Qr*o^X]wu;''˓WEWG p`]81gW4=-' "v=VUd#JP pKYR̓h v; ,!Wɕ;g*WTR|ra E(ܼ=^UF|޶!Fwl&̨R~V !\}rB樀Q"ْ*FXORQcJbN1[ 2u;:90KW!wiSJ#&;7C)I>C{wu8N&zFVƐk-gF墚dOa/#V)hce#KMɳ9?țFS0G9'`(TS>8(6KRB"U,DVhG!֠oK7Ip,=?ٷbZor6GG_\o}NZ_;WI.QX/q9u"aLQד 0"*T K48!_zuJѓtzo 2!`$XMvI)x d'f4_򁷶U fݘDv8E|Q*2kxr|8?wG5* Va 3Zz4[`K 9'MBK AeIKrZT7DMi Zla++Q[ZK7"KO\aR!e8Rlgxh6צGM!GXwMֻ]mn7Wכ7#sY[ꢡ$`M&3;csTQlIK 0nőgF2iQ|wK2N00ke'6޻,πMO ;9yr|090H2Ci}]ahAyCn\vI"ѰC˜v¨[l6mkdͪnv:|mmlY:9ګVgPyNưZŊ`ZHBsST:-Z3;?qjkw /s2`>/j>[GSUCLcmaLSWmZ%>y9dJu^.fij156 rF3(مr+_` lTFVY X(YШdbPCX8* !>RI<~ u4sVsrҲ˂_.3 $.xo7uݿv]LHd5 j4.B}<{=^o7IהX1J*" #AP|;.Dbt bL1G$PAV-뼯S=hG]*$1 IO^}[~O˳_0 `^4zww7k,%bt/2roQ+Rv0tÆޫBP& %4TBsQ),Pdu ,&Ū[[[)J1rY<,IZ{* gce1euH:IT/^7o$j.D9<pn xH͋9oDjRGqf(Lʜ9ժ,k]*;m5ͼįVhS)Ip[dXV;{zz*öXWĭ6|ϒU|zVអi K2`hy9$JWK%GT %)FUC` se=XŪ5Tǘm$15hxRUY+S^F JjnM`}}~I{ pz> LSh3?VC{Ãw'_9fAU4Qyɭh ^W/߾-Ve g֪+ĞRȹp9!Q˂!ҷU5Pc>x/}nv ֡fLf3T򽕯BFH~h@C`;(O@.xJ!˚, BF8@ȐQ;gbN;hڠҿ4JDR*g& e˺ &Iiqޔe _B2J]QK &jn;L{J1ovm$XwdkJ YNK pdtvlMɣ_'m&&hUq$LQwRvw{wom`IVZb0 {5m{ԋԐ1RJCgDv'o/?9hNO5ի/__ a#PSY`q #G@Ȧ4b[P>eQ 6;Y Cz$yk lr2 w 1Vӆa#7&ht_)$lBٜm|}&`Sd7mLbPM*xX):c'ֵ_D;JDZêV XE9ytR088A*y]>5UՐ)㰩J&gP-A3R:!nBYb~y'm>oNqu@}.-JȐb +<QbB"vE#gQČDp7X4چ1Kx*7[4-^[u,eQԺ1SYŤEP#oȥX) !1U鴙&zZ{F 'mGKH \Dh&vhܽѷ Cc*6kњ4[PgYU5266vԇAgjJq9ΧKK֠ Ye5b6֥%]CPf}:r{8DhMa./6Q†sVm2_9Pt`J; GIe H7JڐJ}?H%L Bj;Ds b1k _BV!bF"q@<%f$4%h`]4 <'#7ZW 8@QIH}tgG{a!+G'Vd̀,Y=eFhUEh۰Rw?O][onǓjC0+KP;)󒅼~H!7d0x}^, CƸdIyQ cxh(L1r MG1"՗IjF}(wz~.Q Ww" :ĬX ):)p%pI P6SVTqIeMh%]9EBܔJYLCA)! ]ioNzc ac aꓟo%Tp-ɣYZccv>??v'MLԂˌTlr]RL!F.CA.M7׿պ+TOӊ[fm;ca]Hu6q(`E8Q&v)3SIYZ}@RJF%du+'J:D)mBuR"ŔY6ע.`=&Sh }[2xkc`'?KG|l]CQ4唺WISFW&9-Meˌ2f]E嚵Y+"b YS\.\f0.8J1DB(.3BNuԳY\z:+X3 _Q)@8?C%>Jnm@ziB:j)SWK[AۺY?^.Ʈj, )%J;"Cºpf;2i59nKBLw~bi , u]<,l8J0 !]]\~vSyZo~WnAaHl`x %bHE(R%շ1f( *'ٝCM0f]hij1=R(e$OlF #A;q%M2IWq*e ?Ak9I KK qQ2OcTd͓X) <4tˢɣyTvz>}݇eU=c$Hah];ם&ˊɑͦ'iT_5~v6`BQZw9%ydL7~"' l׫7~Eq4Xj罙mH#NV"S`WOD4VGR" >;WXUB쑇*!:'P鮥"jK5tFC=-Qb.N%XUyfTb-f-  w-NS{G|]#?$mmy =/(>^2O6}2=Q}`DĊ9 X~ЙW/J#))\52Nڕ4%Cr6zgdgcC.VgvmmnIUՆS,[,i.- T!e|P{ЦPAغ/: iW!v {VQ ӍdL=ʠQPD˅;LlI$* 4*WcH8T*rx{U>~˛TFt¢sb\ I*̐qrP(<:ҙV Ԧ]blar(WӡG_7^n#aꚧypzßkw2jReX$Kom˫O($Kvn}u k|eMMi(j/G J!Xh$*B.b+'~)D*`%]nҰrZ*UlA-;`S'UlBU `L+PjmqDƂQ4.8bc7( XzE=.6ao?6R2f2hPh\DA)V-U5;)pKo7gU ޺Gbv޼zt"*vD2Q_xu%'@9(mcn.o׻[gZ #2@! H'J9Xt_]`mˈ5ZGh~½MqAJJjr(,@CCsNU=LaJXZ\L%FF1ݩ- iHjjmVު TƝաM3[r!E6WarRj]f˃O_~:eT$Molc'~עmڳgCL6qyn2NW]4ou*:QKg"K]{+ :f#>(N1FK.#H 1^/5CVǼ -=)Ee:=j F'V=Cvd)g-MS'NC 8Bc``rw휣d ?jO`l %HIcP&Eton^UfZݐq8~j@~: [He>^•Biu!¢ߛU#ZJ*i Y\XcE1idS7CnCU! x-KfoߵOfCθ[g6 np~eWDbt&Tw`{cm,)Cj2fͼn\Y_wC!sy{2ieW~8["|wޟU ,S9ŵ6!bH:3!htSݶ<ؔC=u„Ghv" %(dĩzgd-䓢U۔Isj%$CZVyPdV|${R%8n@9'Cr0 w%0#&d}:m I1$aT*d>EHL)PZh:)T@)NFID"QB(Ǿ_ZHBLh OkCo7Gd8!2Fmɵחds8?j:zj TiȽZ/1I*y[YrNԻ'?(g%E3ʎV9 ywן]=s͗ӦY}z:1ֹ::K+jXT"E ej*ou ػMr*%2*jrzC0"={W$#eZ$lJP謃pHz(iHlvdXfBnRȼ_6}%_# #o܃Wr^iW)s(n&uk:Fy|SlNV%#:!a~9`p.7"]S՗'v{bpy:}SM+|eGR4>MdårZ#dA) يSol8 E[C"(kM84Q  V*Ǵ|hP)tAcBRm>{!Q*a%=qPжʎgJbbc,\.^ژ%Sv9ɲ~9cCJ]Jqu{bRmܴⱪV:QVo^$}zc2Wo^Տ7æN䪪cY&*6rD.%HN1.'sHXn91FԊ˯ZOMRE:UP(glY(75m.Yu8mq9pK=V˂:lI㚖kDgcqi"n z|mv4NFPx(tP@P? >N ;g^-&Gd۰mx^ƤE + )ĔB O1 q1NOg1d BخHMO|p*88l뗟]RVSƘĒb1+– ?^1OLZ;9*P/NaP=RQu a<,zfq^l/SJ&|1+b*=Exh(T'+(s8hL5"k]Ȉ<YM<_.usC`.n?=4!^1C aBoSΏN*:9 0>ԓ^B_~Ӫ zs4|>!cT~ѠՅ mUOzLQtL,o 1][J aLM帜m}P9tCsIZ.yɽك=͌?%"pqG`R.FL+SLY+)*eDlIvT$VϚxL9 TFk"?Q&u1y5\cS:G4M]٦M]U;8A B9M{i3?hYe%!z2h:QEcyx>"}ذ.Gs1ޢI5Q]s&X;'> C1gO4͛KƎbWzi*SrC,bu>BƦxX0X G?(Q1/~E-(Av",Xjx5nEbCַۻ!:Z.Z=MlZI;5^uX*_mb}nbmե~ˀd>uh7wS?/u*G7I4 D罡KEm:ͪ6wDcߖOGvfXS#=fr>9 B(%)ܩР&G!d0 eNA*z̀V%)5AeR$ZNiwC"NpW;ܶbnUI2Dۓ+ߜ[I,`1)s.ӿB?hQϥsr8䉎 7& 1؏pS9kjɤ+tݵ( *ݓΗBk,cVME۹cGjLOJ+b_4<@ϣjyvx1̻pj&l۪kt_esW\>""aw0uFv2sʚv[Kc"^J:R˯E% QAv0=UD\3Kr!R4lUUje7a޸jgjjW7lv՛\0 9H%^ ] ?2t!8\o,NHWYv}l.,O*Gf|"K=el:cO?=̤gYi**&~l(,1R$v{ e٘{zj8do?9+p{,Ö4Nkvwܹ5shiyB~ 7O7s9I6J+A2ס(8z"G8+ 'T&ĖvDlCzbiV6ز"6 E䑋 ߣlĜ?vn*;Pe6! !aȧOh:\S!p?pX_c=ԅ2XؘA1j j ٙu.Hz]KiF[3`T=CγIl qB<zش ꆎg~9r!Gtz**92M$'(ZM߽ml&Fnś۫ʩ]@Pθ)3̢*_q7?uYr`vSXacv4r,t9A87m~䛇p(68_& ?![} /fBO^oګۘ"37UHNbxLC*#s텔T|kLJ:(1.IF)4bi:X܀Y;@V9eD#/c3M> zB*\_Sjcb`lwgY+>aȥ*h/CbƋj~_G 5Td6o @0Լ#9 fLLIlH!D !.>dՇ6(AI?*9Mlz}R&b`g8lF鶂(60ІІKÐz!D/ϯ\>A8OpD2qKONF!-)!>}?xw?8~NN|7˺~=rVOǂ30!h]HGicߟ`mːv5 r2_w>uRR1aiz}xdƙy0f tGZk0Ƅ\7޸ n^߅>qvqͿǷݚ~rJ mǦ )1 AVq7q1D"7҃)kz"Wib$CX0uQxZqgns_U1c7H=6R۽M;}s޶x.%J}sy{q< ׵n%`j1neyؘcιVUڷM4EEٺ@r$b!#$@#?9Or3 "c qXVD1EQ%^}VUkyƬ֚s\ m~nxwoQ16ΰ9@% h/wy4>Won_. Й4 12u<;llGӃ4n蝳q 7~ϮkY]S9 en h b 8RCJr+ÄUۃKvu]ңn(dv~gË?(qn}S89W.K9GssIK|{2EjFk7CH 4#iwzr!< !EWH8xHlI6b'L SaKI0繶קg_ݽy]Dw7ӛg^Nr -vgӒKG'|򺔖ⲳ؋Ȯ_\޿?}X|:XfQo/MWw\Z?UW|~/Urʓi\huQZ4GOt5z=Gb`aj?Hx;hv{JIO:_bp\/xyN0O/fT!OK%(I?;rs-Ԝrs:i @U ,<+tcp@uG3z%#rB 9G*sZ >C`E%Tۏ+o_A* y^}O_߾_~9"*,1ڳS;wIwyr1w^/e~֏wNF>NF* <^eNƍGZ 8nJk<̜ὖA#rG4%כԦiJEj"j^Zjܩ7FΖm?f]`3I!Nnl! ښIw00U YZBD}KNsIj twu} $Rk*템?9s3O|~GL/}>nhDǿտ~9:9qhSR564%3ׄ8J dgM\3?$^~շ_׵CZKK1 (6tU6'(;[ 8F9rvz)=yDa<@=,ZDVg@3bHV0;L˒=2R8|p,Zy$Ynưlkɯo?Oگ ʩPIPڐUo>7aTSj m,N$D0Cl̅B͗öB$о>`+3/M;ԻZVbhq"t-)_r̀K:Uzyt޻X;|e>\?^έQ=v=ɮ~ѿo~LY5fK#_$"IE4SqKCڳ g\8wۛ4a[9Z pƿd9z.zM1 \R-etsK~y͎d}iTBi=#5n~^we E. 5}AO5zqLJ@ EX1k ::TLaAX6MN8}/anzȶoØe>֛pḜ浿vo\m1^:BOW+oS;{5={b_+'+GŋWfᤵ8Zi?eepR!|*VIh?Ȝ=hTldÓ adG>@`XB59ԏV Ѧ8˕hjZז?zu[G6^WoGsRB1R[S&g_{z/o}x  >R~*vbc"ɋ &\lS1V͉mE bsf^bnK__|ܭ>vqEgw1l0s\>!^v=8+Vo_>|/'xݤ0 K߸=n:aN|H*G7(T7cB:-1Lgq6uTޛ h5=s84v/q<ֲK;ְbu :y!zzv}>3syK~YO߮i4v?p+J:w2wJȶ]8Ժ:)BVA F o&9li"Ff8Њ9%2[NyIrZ}K_ay߿ftzƫw7̷?:#aך]\;WO|Uj2-K1ϭ.GO<<ސy&˲<<_/ݒ眫c93]\=QMJ6LHՐ캾JGLj6 N) p ˥@R˹4Hi cBS~ 9""²Lknv~D/6V2TGGsl{%.<#:&ȁ6Dakȿb0d Vs=%E)Q;~l^OO6|uMO~s{ܙZ4 Ww.-.\8$W8$>7Lj5iR>RK8o I3jQ!]Ǎ*3 .63=-Z;fGysȲ yɻj%,踾;k▖n'^}9jiIrJG*BqEZst0iUE`J&2<1NV.:h44eڊ^&P;F@-55BRu[8?D'Tp5KԐkippqYB' 3F>oocbu0|L4 Zl޽8!-tN_r%vNz]GfѲRB0ݬfP;9j'hxE讍?)9 CgF.6EG7uo4qG:kVVw \׉\-fOrcKJeS m5h5I]A߂=oSDsooV}9Ot?nTWySvHH2չMAWGtlMG!h5J)4NG)dѻRXxce|XtyrO ^ K:X1v;ezO?|˼j oi oÿ+}^G;Z+t,AFb@ Xbb5t@<0 X;RICU7>"m|k[/'qCti}3J]"-qWw_R!vE)\jݣhh9&c}33*Z'Kd"F:HY꼛9_~xl;2I3]fCŸ?/ m*ϠрvkKFUEV<䣖+eU-*`) ؂{wO8ؒ'2xn%<9y˃aݧ<|X)7˟x_{%o{}~ΕC!k۴ uTIo8C! ͯ_lB3Pe(6umyT- Vu8jc0;`3h8q' L`˙DMu?}TH@fR mՋ۲.Rp{άa3?H Ib708X7P0N B7 |9;=Š6a#l5.D՞oovύ>y~~Ku? g y ?4l05eۛi. ,'(θeiȄ1Ss4x(5]M|oj]-2Ҥ!۹N:x) 9@<ːW'vkưMYPֿu?SLp&j9LSOf(ȶ977lr|]J_c c gk;x%4ƕ{M 3h_(lh;?"*o/ooQ Ÿ =*0!Ė`2m9=?$d0Xq.j`bemB=&6=e e5@OYxO}죳^&n%@\7Ru&MvL\=)C` OU[rTGl$ ܫiх܀?y?O9,7gן\Li>,#]ىռ=i|tw~_ͷ^|ܞ*U_Zxm &T5/+?aÔd6Le=1:^9X0jέbKN ϢAV;xo+a7 [ .G>%C/rdJ.ҰɣTd|Oo>Z$S^q1ZxhY6uyPu4FN:" GV"{M{Q)h4ײ~+p &KiO6|-SU%V pEnޝۜj7Ðz9ݵz }5 )U-ZiR_>BwP?kVL+C x 㠱G쪫Ν F,{\de/R՟%D8jϣbimX螶vv}?|}~u7k][V9 kvzGo1a%OL`ڡc׊J](g4W= $g8͢00ei9gJ6Zs]"++/r(^K]#o"CIJW:ߕTBs&huNC{S걵`zc0iĊ@ ؁Ea( oSZANkۆMsCsAv:Ň}iާ9  ciRl.J a=UԷYKaTPiv!7PCiSqlƒ רqGƝPx0XhXCc*ZVdv N's bFeQLʛ-Pr@šXC;j8CQJ^p$7Gw 6}ӛ&Y07OݳwgSBo=Q7'-F*ћSjЎ ;C`Ӝ(V_ClsK; fcXuWf;/i?O)/Pua5lZ[]톆kvyryyu=SQj?e%0]OWC! :y \zVjZ܆8,%Ɠ$k,8D EcV8e]!.\A 5 !ZE>UdZSZ ܰ%Ԡ$rm!\G"^(h.&ʍ35:wwz#^H,où sKs"f `aGCV/`[: I-v潭8@,f}XC/yg>y* :B$FӴo>aLiYEy<;a]oPQI0uZMbyJɨҖ >Hra9\F:8_[Ti oZPLdڡƣkΪ4Y@L έg jޥyHri8F'?0߭VhH%J&2OôC5>xt{`Lt<"7 ZzbBLjcJjH˒_;O޹a󜀯)o> aեߞ&!\n5IW7JjT暝7f‰JI$ }5 H&7W26Vsdzm;ej(fzC-pԶt@w{JfbcMIkpbIipgz~sN'a)]Qq9lG3~ f 77xDGC{0Ʋ}`ˁ~tSaT:."7[omDnaJˁN^h:ka;¨/i.8qV8 !\Z;4jKY> (ԥբz0{`f֧4>,#)ȑeo°hqW?n̖Ŏl*ʂ n\&ط{՚oƜ8MB11 nuf+7G\e p [ _j1A9yǬ!@E4t#7F1D2v1՞NckZz5>~=\]<>?8ݜc\d%M49\RJe:n^l^˷j)yg |!!͓/15mdƩfoNw1לT986qJò~# ggX7c[@p`.BV1ښEFSr.wi[s(i+)2jWdzy9Ql\vx&ILJ3BZ]֍S*x.gV78 ;ȿr;Pw=(xݫU4R;jaurz~qzhXcisMSw40,)Kʐ~-^m}disNх!RjaNƓ0_y= ֩-e޿gY<HzK%L-FWoq ARG^Kں |Q ,KvfY4X;'b*ptu+LXl`\ 4Nv*C\ո0|a1eQ*f>C`+͸/ QkFݒ$,T(V =dWrh929)v4òLz< 1l%#1!v]-(NK*esk] ̑!P͊^ &8*Ӻ'* Im+P#F.t@C1G`4 6Sgҭhǥ$ Z{3k}=0v{A]}aq& BrRH?F_eVUm\L{srSg1ipQ#7I7ѬA^Osk-q1HޓgY>@t%/sZnуiCrg^kh—n^nNoO/g鲟)!rܲaq*ev{hI{~p~6o%ubldMAKfu>[R0ET+']B`v{ S05u>jc~G>xעUǘK9\XC{C!@:{%5KV/[ݔMk㪦ٗgijfɑ+.E/ʫVT׃:wyOӲRӒwa֜Di@2$`"zn;6yJ~=TZnk͵SP]Ô :"oR;;̨VT"-- 㺬ic3#tOolCZܑ8๫! {2*M.iN- n&b:֫/5nx!9:#K5Xyu?|J̟Vxa;n)%Z<ʹ s.0-~? ,ZSJ&3]N(4DᥤCynH ZL3p $ Ln #ҝӴ(" |~͙ѵ ,I(֖/ePE;nw >=F;~ߒ Rci5W_[2$G6tzB~vƾ >?2ǦZ~6gT_&n??1v q`@zj'"y M4CØZX?[``:ZdaiY8RgFX?XF2_)Ur~(IY[ uv|#5;r&8}l<UnkJb0~NWvGI^qRއ˷`|U x;@@ԵyjY]J|TY[E U+ѿHs< 1jj(bnS(ծ frAH;kbNBQf%9vCo'\0iԉf=b y<"!<18m#X22Ϲ`-ٹ %g>'QH:ϖ2"aǾ4)H K`z: "PtH"[Aیjy˫SGm}\pAs*Y%C!1駟,<ݱf'td&Tl( #Ft (  cQ#6 \@$B) aLN+`cfzmdEq}G-l)iP :1h3'J FP^j 1\W^sFBdt{| f\_m(4ڃ==f7Nt5q MNv"~l^ݳq˷~퓓jݮ2nĞ74YVqA`֎gY3)Vq,pL#rj5&qz!"^ FIfȿf~rUeU,i]i͆\ k0B}x>? #k<v4pG6ȕqdZk1K-\Jk#PH"r;NYvd*kŀE~Lw`n%b@,_09>xӧ'Ͱ=l7CE;pEvw9ܗ\y3IQllȎQX/?&$NX.v#G&OU2Pk#?!e{~\J9F*5?fA0$i'2R`4à} {-ˀtN RH=*vwEH A.=_<Ӓ\"^ZAkN@HsQ FGnJ}nobhQ#qRFSTFqQei Q_vwd:_GU=\$`C4y?׻4$}G>G17o|n"@Cӻj%z,/lŇ-;4 )ٸrF\08Kb(Y t1+VMumT-6M e@\XlM`ΑkgOX|O:9M!.F91@&@ T ӄ>ZaEɌtq?yb K0y&Dͥ^a<;;[M$g4isJӲ|ne*CLwtAaM<}!(ɻ$S<:1̇Gt[*P&Yj\a] r&vLTL2{.НFmH8o!0zphF6A٨H8DI)9V*$__zȡ sG,co11s`ZiẎ/ee2Pyj؄=ٳÒwnyaɂ]lT4X?R&T^ϩØ<<˰Y?'oNOކPqV(8_Vƌ^8Y;-̹\bM@2HK5䂞/?q~;ka r@8d!-G392i07V1sEZmaธddEkEؼ έ 1h'r3F1pfoD#0 }icJ%lHuRn@&7RJ^Z Q%P'OGfJ|z;]/QCk-JRgnӼTS%JfD?hGf}Hnf2JAPئI_?ڳ)n NZrbśq6' BP#htg L4zv84PX ffv V(% lcijz"м{N@kFl\61khzԎTyH-`K%%iʩֲ}ZfqofCItd7(+vtXPx`NCaX*^W)奖4ϯo^S\Taʳ'[ˣOR׻h-c!8 *c)X#\O,C1xuFXa=1 c|s`ߎh0 K֜T5hSЪ}ޗ$d+^'CS +}GR[c4E",[pPܝٵ҉ d=tpݶ%I5.:>kf0=rÒy3[S>xu1^嵊a΅2yc Qo?Yť^(>/?f0r.S$>%ʒ?&e}m Zj-YرepJF. EeG ~!meQ/U!Z)FVa0\jR~g:63 W K) ҆Aadfa6D4ZlpBgqVB\905,h J-Znk*{9nKp !p]e; ɽumI˼/oޜo7YRi)G\d 9[i[ɣ4Rʬ--|zqtArM+ z:cR¡ZXh: :1Qp۳;# ":!6e Ѧ QsFR8 %M@ ^ԴJ"sNU%+vBV1lKC ";3/3HmH#,j: uc!Ë!:v>bc^4q &^DZ(y;{R/sqÑ+1qLXԦaU/nǻϼ9mQ/dD-ÎJ`LaHZRx=qFcf3lXb 6YsWNkl$jIc>?6&#]`uJaՒ (3½h;'N;k)dw|&8er0v1@еoegƌ8͢85/@>Y:-PMsƼULؐzMt7 öz$ku;v~b*eI?1~p%;4؞048 q{r0w!B\08G5zac'`9 P;ִIh6] mXo0BinSIK6^AaS-RHcF@ x׆cl~18iT@h(Zw)BL+&NZ+)ΊNlE<>S-j.-C0$2cJUԄ!fK;#ay2j}Ż~3nTeYSlZMX&p밊>~M2wo$[&궁!qxln#F[R.i5Cac},X/H]Vo]Zɥ\ZNV@V_9$@"8zoH|Raΐ"eY Y`Cɠ,.Ֆ '#tVNz2xdDIג`rsj?%Wd]ۗRĜ탏ˠ_BWI V[Mm9AR΍&H:=3kNa7Fط[ͪ 5ڪQ(Q2z5;ՙ`cj״3F*%b. rd9M|Р[ 3xZZkQ;BVԧkqEpS\x/!(o0E[%lL(HEArεU68,]8 (Wke)- m%^㷫,VN.HAʷRrzV٘j(ʶnϲ퇥j5!K>I#{}&0\@ 5º ٗ81u`tSc+5$G)&r]l ɳ_58ZD ɞbıXaC6,PZl֬tE^jQTE& !:U²Ǽ}>67~HPWbPҮmL6lOHczRRN0K"(orHP|y u͵bJ7q|}ҁ;2`I[ƆVsxP} "M6Bj(lC6*-d RIDATnCĚf4[uz%<-iV .y3s5<@f9O5z#Yi XoVT5* VfQRG0ʹ|Ԏ5b[`VX|fQ.cpZnbGY Ic<Í3ƽ2pMm)BlPS4JrMy\%TTrưUbaom|dm$yd0 kY]iL)6G+jq^D;VzHS2EXa #aM>N36g{L Gp:u6IT+0{f6Iojū)h|@0<ڲR jȞ-A,[ЃzL"X,gl9 Ej;T[%ZjeYRfed* B+:\ۼa0vF}aq̏aছqq*<6-]Q#LPj(`@ۿO=jmJ?(Cq 7F:*o|U硇)ffqxq|4=HA6<Ѯ,2qMy\EROz^>Y[P]s+^D'КAצY A=WZch fTGΈ%-[cO;RL \Ni0('!nAlZl5y؛eɁU_=KbAbI|@NmW1:ϋJ2@ěQ,Z63ԺHW&ȻۤӬG!BPJ^ECc؜&%O'b::H'' ]-KaiK+hj4NYc T,`a U>ͱ 0:Ǡ.%EaZ%i bLAߒt5bhBQ18p.6GwRXs{0mI0FаU*yI 4 j_*H38 G#(YOk'z]GO_\_6UW'4 #J⊫ap=z2P,o2j=HI Adaպ My j D\ڬCZV0ыZW.i?-iY4)%$gr1N%\AØ taVV;JЛ]8|2aI(O6^KG0( zB˒{V#U 4+ȆQkFŶxs*i 4xFU<_Z ^[I-0("A*ke p,,.H' ?*SGYZ#7AS l篕:خݷ`,Jмkz3LiaY˴h6|zt7': {-TDaqrͰ:9a_Wv^T  tъG l?Uy"5 !{SMʈmhPxZ(S O1M3[Kg1fZllj(FtV=Kd%˒V)--7E.SlXj^G@ujb5p=qA@#8pO˘YeC MOvX]pI}p$w4QNF;iݢx"&hdc+Ù*o(p7RUr3KH-È>ůM`ጉHV).[_H; R;,\4d d8RIsӲX̚j4Zi[T*Nֲa6TfݺW!ut 3 w} zF,3ѼLQRko\ !avm$.,D"[. }o~{6$%1+[Hש "f{HdhxC߁ q𑫭\[4^B6]zCd{†0g1@ }j㢒ss)Ӕ)iIZT T9 h<HY*sN=zpl'QX1S"R hO"4۝6hBx׮r)ٛlmco#op̀?!]ԛ#cqq*-Eha?&6.uǐ2}?JܑǗDљ 7BA08%_`SaI/jY TGa箧;.u680 @GZi4-?Ɋϴ+FjqlKՕx;@"O>>絞& uWXOڣ>0n-],x11CaY`7j ]}7{N}6Ǎkff:˩{JF9Z[8:Pt*ԣ˅]+%j52N h. &r҉\ϔQ/>+0soJ`cc9 Q] U!EhIENDB`gift-0.2.0/testdata/dst_invert.png000066400000000000000000001040171513354670200171530ustar00rootroot00000000000000PNG  IHDRxԅOIDATxLٳ%IrGGDfK]tb @G&@d2A2Az_Af2L0RB`0kUu~̌Cyn<qͿᅩ)MID9YFL1 .(E lR)ɣ&ҙtDI PNI)ʨVdY+J)(>G< TYiEO'O_*@Ai 3)r7DI IS" :+ߍ;?v$@^KƷ]g///w]}~O}ë|zo87R sq/^F߭w]SWgW\-=O~*D />G?r^iw0=yoNO8)DS9BQ*u]Uʽ sVZkM*u\LN+c*O)sT&sx^̗{pc)PYBZ(9e+4JgRZqq /Nֲ:CDI)f*RurJ~l1Ŧ7D A&o:dBPAJ*EAVZq@*UX FyvU"EH9F'pbOOz{g_~p;Uڱ,g6A]Cxg{㳧G{GGH/vdOw,}7R?B s C@`5 V.WUx^s8[QJθ F*"ƹQ6ehױ)RΘR/_=f?͖5SYiԠСPȡS&TV(gM q@{>QqƊn_[I)ubnʣg1{ o7AVQ_n?l*M]cV)묍Ԉ j A!*`F!$"xPN)(r I~QNZFsig/G9~=ǕAq )$<)f V>\YrNG8x|tNrNY'y9gdIv$94 p/~ʍUw39,Suֿ1VIJ8pzuY;_E.̗˿kc=.IxK&8;<:<8iFݽQ3!9ǼU%4$k5 "4J[sLھ[7yZû٤!id|ՇV/⋰ټ82{vy|.9Sjn@̩Bޑ#ӽÃW6ǣ Wq6k* Un۠@k헩R {2X6 rn^%gl-M֢s&FlQ 99l^rh6Hpf$vZˆKHHҒ{I^bFQ*H ~ Ӈ˫swjkJ:ueYVy?ǿÑWۗaPK2Z,U$zk>kSz|^==M,ۛ[3Ո&$Akjoۜ),0vM̟~uv㻖W(e¬LmucQkCb)FI IH$DB9v G3áLMfZHuSף5іtb%QJ ^t`J&^X:(SNv2f`vU91HIDu11r O׷/^~1n#7 <%L./ή R$iYʘ჻ۯF@i~/y̟OR,(NƟeرٝzy-Uԟ_Mg H+Wif~}Z]'>^5t(I=Im!︼Zl}3yxц :L i:kHŦ[VIr\HfQNOL9J!f>_\.&{cFa Q[ e>&3TȀ*P#ŵ,&٪Rg% hSp)@ <) 0Hp ,^wzc~Bb͡.B6}h W/_/; AQ\y1qY"קD 'q4LTx/ӅY}J .n6 %9Wi0V!y #ǟUXªBSrzc0W6'Q9R1)Pl-h`Ѫl\Փ/֫F 2 O8-q9cl45(^a rV1hƙNL)bϯ/D(,IHuHKNm8a8'[1S|̔7|ztŤV׫7P DW!"]Qo[ӫ($`R5 J}|RRuq X0*10_;vl:iױme 2kS̨W] _9On}딀92 Bӌx޴]m*&B&J$PM+-oWe{{`O1I$E-i$'-28=9gZ_!E%sdJpĆ\"SDCL< 9K& #bh='//f7fR|yAcXIwRnW)lW]8?|tprtj@KxH «S`#23)݊שRMH]\7hT5ʒV@l=XiBd¬*8%Y9Oո>*CؘFF1rMm痔u:<<9j7w5UD) j94R}WW6D=7Ϟ"*c+Y͔ѢGA8g`hNz%Uyh1CPOC-JoyΧXD@)1O1Q,<$ǔO'E]7M3}8(Rpu>:|6"F=~[qxo<-RԀ,VΧZar+[!珔1c\< j Ũg85R\gTYvuv#pTߩRxU1XtM5kV{02R2@jBJ9tk\tzƫoW'|'}ϫ@:ďd:.O[3f~~p(k#:'QC ʿF֐ X(!Z:!:/J5WhP !0Q E'%^K;AW~'WW׳.(=l3C (oR 7ga3ߤ9jaFWx6Q,:&`lƱDqHI>$䬞$9Zc,2lՆ6BV!y~0$ȁ6k)' Jh٤#D6s)D$(91DJP0Rj|q{>=O N(5"<9,Ff|tw^#Xo./m]pD#(Mijd$n$dJC'l_H Bs4CA{i>X{q!S I( p&Jy29ٿXmMmlT6CfyΟmb/*T>gJW0jdM^ZT\]I$ʧnV eπ|X 5$-Dss\/˫NqPDS+1|R!g):vZQڝQ]xS ނ˱ >zB1h"5_.6?[QH䀖^'P^!^+턖gW/>U:MK$ JhHD (蒓Eix 4|2p ?ApзP#/Į̏C TJБHm@ +?/آ._mAċvq&@NtcG\;T!΃Ec"9sh2WJ YY1-//Eyad,h#.Io5zn1̌"7R܆W,K@&C\Gr}Ez })8 Hlʤ3V1P{J)Xg)JI%?UT@ DrKG$o[VNzP)D󠏾އ%(O`)*T J.h9BnZ,'f]mMIyN=j2U=w&vdv'wb*I)B`g|1Oq3`V^zy`=VVθjf(zk?|2CFa(Zt%ܬ3'~4)Jthp[-V&ńљ5Ɩ:y1Gn|ˬ`iYT1}Ӈ!}z}c J隟Q) `˒Kth?kKN5#)k_v*8t!JL@5(S8d9Y Sc0B]hYCBaG,mҐIŢ&xt=+TJ>h:5rZ-&SmAy墿hfLsI7` rY:ψ qzS0 #xu3],m;όd+2p+aTQ'EJϱM(j,- *ġ 7)7l7@)vF-_5EkJgqWFM 'QDJ gNfLE헼^) 4ltyg:/W˟;N9l lRp~ާ/x+v1!L&`ԓ%Gqڸd,B7=0\`WT E\@UBcXD6hf}bO?Gv^VSvٗ/REy"ʒ$ Ic>%uus$2PX#*B J!؂ EWbgS=Ţަ^$%gĂKˡhYa(q%FgLӚ6u>~o?>:6[J0@-ĕVj6uSRB۽Sv$ eȉE!2ó ;8NWJkwܔ7\8]K \h`x6M jRqz׌wN_ޞfrȆASԓCryXH*J9X J %H++U)ULaRb V;@U8Xѐ4K +|>hWJ3 4 ڈ⒑#־ ٜQYuK UVa0)ƣfgy?ZU,jCQWt~5w2\J7_?=2-W|NN<\/V`21cA,I9UL]9Xor|R 1c:(h`kyя>{/v6w!n:Ǜs>|R전â\ܣD%r=m\NX\fTo(%g#>?^pޙwP*RI(BsQC7tJl( 0v⣿\o뮩ᡂbZ74MY0<*UgNT^=dܜ'ib5n! AaMU7=:~96ZOnҶteձ˛~-]Ҿd5fkk] +>|3L;;';~\+%҃8l5Z%*]B#ͺ{/`L12BNaRj 2_ʣ~8RZr4EJ("A)aS }J*ĩ#{Wq.p-6&\*2"-k~VK;E^MєnqHYϹWC\[Rn1!M4*{jC]`m2PE v)JHqB XmjekvdulfIыy3뭱8-n+JsBoճ/_<ƷttQ޼̥[[$/FQ@kcR'k.iDSp.xxUA2/ T2Ċb;`h5E|!Sbwc5 #K6Ԗkgڧ>6u^l6hgu.F4%q܁ҪDF5\;hRq_i>u?5JSK3M8>H'M4(Әc  160j[j:n[jN9f˼M-bp֢- mk(~7KQarLx!m@ ۓ$2ͨiPAϕ>4[-S~2 w΅֨c6hlb!$ݚҁKJ_#K}K"+WTUԗPI1NgR׫k R ]^a7!̄3u[*L*&R[FSa}Gxko[2PTFuN䘳Aޙ^Lq3V&q*%D~t켼Y/}L) F,Ae>!&ACTPZ9) 㳮w>zɽǯX@mMKWp!E&ہ1|#)dBBt-T_P1ya Re.\7hy/Lek[+zoꓕ5d+3P\z`HڂZwk;k r z;3Օ=T9[KihAANstm2FF/ڳiXrP^,bHA[Sk[y2vm}ۮ$Ybay[J 1(d2^7_/.?ϻv)PMʹL֧~_؂d~ia)MzmrMBpC(Ns(G31:R%`%$q$v,Ő|$ bK,꫔C䶞S\8qh]8o]tHy{d6)&  !=T6F/kry]b4u lGw$IΟ>svUZJ6XзaҦ2t{ptwxl~}ys,|Y2Ic:8^+I62HWCM1ڐd;'U,hEmRdlGbQm}>*1@2"^lՕI*y/E-\1V`Ρ8S"' "2!XTS^+Y`4赹h;U3E;ޙjbNkI ,!j8 F+1pƮ3 J8pXff*[u~I#ti( I([fz@eNwG' j~yl7ZI3!@2ƤF(cJm> t@`Fe5G01Ʃ@x w}hv@q5) fJ3tfB N.ʇ8}B4j5x^)R_!U *)[ErT\E6X3؄ݻ'/t޾Z7)&I|E3 }\<~`^;~_E2)@ąϿo]bpȈ]8I!lJU'Jxt2Qo|rrL "Ee(P+;d([0Z[ <+"\OS(Fm(h܎%X'eo 3ӕĀ)7 d XFCe /F[MT*CPB@![!T4 R˸QխקG9yk~mEfyPrcF՚JU؝ꗛ3 ާZ[Sp!>.>/kc"[,-K . K;^{cP90"Q+ѠȪ}dE](,ÀZpK&(0 z#*FoK6jޯ\5/c.ŧ".^TB?eT0#ŷCHaJ,/ ^jCKαAJ_uYjH U% i&kV m=ב+VOodvD maOC 4V^o@S?&㓡n̝YV/$UWK*AN?O~xl4 >RMX_^]_j#cjb,0:;/xUm:<V,PLR)Q4Cc (LR Q4\tGݮʍd҇9D0t\ Eu­<={8G,؃9yJ_^PT _ MڅrdN)hͭifb'J`몴GA18 21vzcggN۟k'P b㚯tFVUuޣXԔ C+7{?O3PG_sx˴A{t8q=ڟ6U]r-vTan.(h0"*GPѭ!rdj`iF9)2%PJY*7y JORrt cI4>64 d8Hۋ ge/RN޸][NT混iDp2the"59=ݼRq ӀA}W52N$ʓ7ήQP|~@vv 0cb:B+{8{0(3js# Pe夣N9{Y4 Md REZ1@住>uY15Y.YZ.d)')6ERZq*7ࠔӾ4JyЄj! pP,a!{.eVu+(=A(>J"K3q&⽃q?~_t-I^+avd:].+[G|J2U-2g/}mڐp;wRݲ_nP8'(㾚<}JylޖBJD*z:a$ 2!e$;k Ip'XH3/H}=]_Be9Wdp%IQ@#@ Y %U⼦K#i6:2/M?㋯M.b m(X.R4%j[UR4Oު~s9Є-:bNt)ke+9+$e"NQд&RrF6S-bĜ:LYSkrh JzN o~ɫU{_Yv{-EeҰwz[7>72jkpt͟2Sh\SL[䤛f"prU6Ij14;w>AlKqKft#jzyiAƋTeHYǡS+/՗IKDOIn(9Ԓlh+-FFJqU֣S RH.U@ { GŮ 4zB9[2XҌ) -\c "^Rr\'J_f*mA l 2LlHJfK{ NTq 0d>"#Z (cB4hLty 'tL!hz<9x\)f4$Q*c= 7(Ilas'UBVLq^HZR 0iLI*V.!1l^( =̬2YjNuZ\Q]MlNM{51cՐXsU=FPW/,QkcJ꼪8De z?/df;%u~j@I lmſqۯ־ZɵT0.r- f)d++R@ ЃCۥArN)D7dY7=JˋɇN/.Pw?Gn[ZC⇉$HoLd9hLVF zCGD(*V\rѨѤt6ZF1.V,m[ͥYʵgFzEv,%y81(BCZ0v UɇU[70gsK ۟39 2\cqŁ,C Ff.eRn؄"0qp!l#7NH]ܔ#M2UKc亱A.ԒEhU@]e?CE3z{c ǹw?oMS V'.}?R,j9.\D[3AzɄ_..$C Fv %xoz!i&+Ӻ =y+!:Sj[]Lj[L1Z9ŐֹZt9ؗ$oB"ps2wL19K:L~mF۷F<]rPe@\Ǻh"}a-Ne>?8ۮ*wԗb)ɩa jJ=I.KFifN?4Fյr]8k L;rm[[yAk$i9ꦲ,,QrE6CUM+=UB.9kvNVo?hX0kDY~a /(cJӡ({;HLzy݊Y@fq46ǯ7 ژƷn3=qn:Mjfq0F֔K {1g>@eMRJ'&ڿ'VPR(Foqž7>>IWU.bܨ\(M4/ ܓ9t*MikTT յnv:~W`Z{z輪oӉo\FXN/>:ys>U*d;rfbFkWQҺ@kf.r`Vl 5h ᾨm%{JB%CI(謫8?{g~_\TpBp=>Ch62 ԫ!mpYkBr/087MܗϿW!ijr<뱞4;[:.hBJbY>trFHYKdY#n&}IUe8]9mkSmSl>E8.#WXq*f7_|]|F z |I)th7T/?R>n|kMO~*HOF<  B(wR#K(,}r5cTLyD#&%F.ސ&~[!U4EA߿U4WOF#МV/}!tYG|@_:^yGWˋI=ʐZٝO. Sf@=)EΆ ~ݤbXqlwt{EG1USM(*>DEYV\_vw]EӦʕyr/c>7E®ڼ?.7>,oFjTܨ#Gj:R_TAd=ݛ裏P:)$Ùf8h+h ) KgLIa$`[)ZA cL4$N(\TlfyyܠPZ~p7㣼q('4fU=Ѽ]D"ᅭwjU<$-Y)y7EeHӋ} Fݽ9Oa.?DTfc/s e3ˢz,|ﺽoS@9Xi只 Qawec8 姩hغ;4c6UP~Í3ܚ.__]/}IҢNk>??XmZo軏'bZL.#fAVkm3ׅ9ErHfj\)cU|H)` _gEگ3\hNo!t1֠36f49qhm-g) _Ϳ߻|y?λM5m;}>>~P CTK .bt|x+wĐ.Qد9jgIo1Y ?HjX㄃TI9G?|v9oW,ý'{w>=@\P+]J;o\̩LcX\''o9BP[X4Fl.s~Mm>}JʎbLc_nzXTA~зbqMp'9xkg\[ΊSF~ﮯ0UzioO~l~,6SzƯ`ɔ֦)GCSht60ThH\ni¨5&J&魈 )\#$^ZeSʙQeGߠYƬGNlQDMNNoWB1'=)2-(qD)=~~Ν7I,Ҝ +,ZzbP"-wsbɝ6m|wO$4Iq<3^k3X$e{7꘵a;!jJ /Q./WczHh̲R](߫n#{vdmPףϟ:#X& meLe+qfY=bЕY 3 w>`EK6r .f%4FLG|^~/ rF_nmFxv8'rhf͋E5EhkW?xʤx]1 S`%X_Ox˗׺fd8gЉ5y OkSߝLo=K`) OW|[9[vT٘6㍄ \$*2wqAH0* N(&iP!備+Sգ_E:9QёOnV܎YJI9mY\lZtrD)VrԹ)ɕ~ i^HYrIJA^ے> _VD9{l(EÞ؀ xo< @, $Tձl^s}sˆߊ}DUf{޳wjMƀ0Es%m"lx‚ CQ//f8tC TY-oyQD0W_?~ZSYȕ'gJt>IECS|뷾O{5;Eʧ= {%\ \O6gW"E'.=6QM>/?~a;l cLׇc8PZINSzu[.p q91K Rz\qnfN(}V/|Τ-k&Z--/gi?1Gp)0!0)|d }60)tMs1}'Cd}P3Ω,G/*qX總z Fq$$vW{vʯpzae!gE|fkM5J^w?!VZzc11모pH\K>]_~go6}_&q*̡=,Lz.> $v"OVR!/w'WO~&m7t\\zP۱8.TB9GDMFi# c++SI<#U P rvs.]a<(ת%2:SJ4Fa>5·m4m?竍$z!ώe~zB~kgqKG?*4v׾Gc<ѯh+LDRGNwtѴgwjI|[> ϶6m:ܸr|!F_9jxWNyHW>ί{ nۿz<#oLBHfBRƏ[VsVi|XsDQ[ӑhm5Fj0 q0" g`\ ]Ec3CuO,Yg 5*&{ &xlK}X._<\PKΟRo~J~_SyMag˿?OϬ=l {__u#)wa$ަuqMit5=Rfd|Y>,s/=oXx7 a]FÓ.RS>9o]?āJ SD80]($G7~ӳ&n'GZ=CF-eI$]R-++ߒVl|T'ۀU Hn6nU#3x@HPz}T%0[\/^ޗ9=Ph{Mgzo_ֻ2Ddx/?>{Ϟ>GUsc>(\Kv_2j@ZVـѭ]he JӘR{q騚8)VG/zi$ٱ\|y8܈^ׇ/LB wt^oOjӿxt9ƭ na[ )Ç2ͪ5g*,Qryiߕc0XuMa _J1j-lšNsdCOZA`aņ >NwuPW޾GzuE=_JN[|inZ5o/`&a4EaZ)lE84ou\]y s9гJ>U\_\gEq_~nȗfH`⛀pq^^r(C(r}^_/W[Wa3 qs6o$ INKӜ վ9ȉ*d쑉AJR Gkk'AH1i TyTN[UJ}CԵ\Y_D_mt>O_LgrqvS˯޻Ǐ;l.s 3]Y?'J6w3Z'101Lx?7_\_|ӏ뗿\L%Tw!<9>n+/n3a9=}p~{jy1H3(09O~Ma9F?Y}q^{W2X cA8DL26qhݪMo(Yk=/[zΝ)Ю(U]VLg!ZÂ)KBaFovqPy[bfr݆wo=)L)D/WjG>9IO$d68> tuJNr|@7QI( >0@W4~\ vDb#K?;K\~KtCӟ?), kR˛;x8 hi-qaY3i-ۡp5$S-W,I2֤Nj|s 6Юxz\*`afr+ohq(8!b"V+S"|W_]qe?]i8WK![J4?D)ACB*DsV@yapwp["P_JC|o;@VVVa5l<0AmN5}>\R.+䃧W+Ͼpq/?@XZ9h6! Gpml%V2C)v%̳?[UgQPcA=_xeQX 3LB CEM꼚ݠtF}w~A8q8L΢8fXT2Ex'P]k^ 1UPH{XB[ru5Uqb$u{S+ޖS j#P el YqvriԤx.:E%u\mq]pNzWfldt̅r|o.\4?(gJ{Y|?Z7uuW~:F,9z bMnTQVk!leT/ BcqMZ XzC#\o[]Z¿Zs>ώI|9ݥĺa#pY1s-J4aUh5'WuA]D  \0"dc7Scw%Lse.[0Sݿwu pn%v2CݡN{0 ?<xG a/fe.TW4YG}R.+Ң4AjԪ$ӂ9z gukh`ԧ3S:cLoI+\ev7Cn_}П/nr.m Vû߂ aM4 60W2HLy/1wi)XSOI'朏K@]Nٯx{~=*ّ ]oƟIkgvvEw)j#qXmM)g6 9xh IJ+lr[ԼLGv-b=U}>MC{r/~|vB{7ojY?OS{SJU]^M{4i f'0o6Q0o4z\ꪏVH^qz~L+,V? cVd(N h_-bMK|\[ٴ )?7\PnÜzI4^dy콖*{{2 JCPEjb-+40u\Jp $j9R6bZBՄ:(Ґ+5(u55s2CeE\}r6ޟ_.Gmf0샏)KΒՇ};.=hYB{z^R9r{I.gJ@^,&bC6wK`ZrF@g|tQ+чP؆x^C `f9;?"+@k_~x/% z}U_}癜}&3CO7]쭂@xeW5uwtY7/o/`m^c8V| ۗCa#߯şVԩ.3DJt)?o󕯆5h_/~+q8Z%S |չB.!5ݫII{eu !VMWFdYinJT}1(URgo|^a8}QH&Mwe]S.JF5x"YWN7\z!VBW〮O`if7o´Χa\>}绳4 \krryioS-/8!גraSYo_/|׿ݷpOO?BBeUr+ZDB < 9YL@T{jipbx9]Jb675.W<W͐uVMk=]ws1پ[g:6^ه7aK y|} 5d䩏9pᦏgCk#]Ƅ\r.2~_q7v8J1D28\[#V9@ 6Cia)}[|UR1Tۮ%/L4iұ wqI9_Wb Qa=O4 =ǣe)۩}{OOm[_wX<jؔaF.Ji`Rt5:`6L_;MʒJ5(vOȤi ^:?E~΃1|q1řsi]4g4dk7rt|3χ~ajB4yg]Z'| Xpky:Ӊb S U*1M%TA#8(?'Rڈ6,} US莌]7 &ګjm*~~YQiqiq;_JoXv䪴ٛZ]M)GJD; ,VUQ{Dl¼~v̿U1՟fi)n{(KciV[Q<r:ʎy (qciY!,$󩺔f'ZXd$º$uS}1h;Zx\>KQyv-6:mB٠I]DjD}8۬)`'". BRG5 }19[UwSE3 D6g*5|r8` KiQkYLZR/a܍ǙT'n4rЗׯoevl7Br\xˬiBh^z3/甖5X 4jR $lA0t Lz2u>Ti]QWus ug xrFȰ1]V:ś|3HgLܓrs@*2S Zf*{:率 J;׬5T!z-<2؝]ze*sv6}3,4.aV\߿ڽM tvE\KχB:.c$8y_ŋ7ixBhi:K91/pXXBe#l^}˒6V Er EL!\ ~S]g&W8sǑGؾh[?vr{Py/rVڨYL"MiwHpI9V6q =A#mcڗEiL=KYkNRZTje@q}:2jw8䢼8-ģs**$ FaBn4F&b(`XQֵծ:M&n[`1C՞ k偱@%6D'HUyRev;Zۧne+\Aq65%4qS3Ӣwń:SƺKOXfBF6?VsY4'3b 9쏇Z^Cyya׎|Heq3؇!q3]\??kZ~Q?<@6,qI(zHy>,\f*ʹxvnk D:FpuNXt;V_(C?dƯ72)@sA 7l ']eRհ|8Hݼǒ=SOB^ F}RyI; `by%qWZo7ֺ_m̢x-^G(٩hrx{/da7nvl0D,bwr_ !j)%-yyKV֥,ŧe_~8;rvP'ǁWdʊAj* 1&lG}IZBP-)h6E z7<S-|TAߒL8}[c4tW[ `ح픫U|pV̵UI}J:c{nԒj6Xt5P(m`c\HRmp!(ݶ͕ķIB!:1q4v3MӴC+w]pI~ٗ+?%×ȇ0B1P9xˢ̚/xޚ3yzRXq3ݝU2] !jl>Yg1K7EfҚ+BDܶO(t P^Rjnjo/U5J!kA.PNdoHYiII6Y f,Z <y2s̔rU[j9\뜎! cx6@F`ƳvlIc&֭`D 2\wXjHXAő$-BMkנkoAl7#1ԄNUzA0j= +ZaStdvKjQ1H܏Hfo4;%: nu4j9QЅh߼{Ɗ\*X!P Mhij#%4LI%;=;??1@A45vn*Zцp}h:0*DG]c5ᐙQQHig`n&TTNZOmJ tpBc&Z{O1Hjm}{F$ޅ[Fi{Q ^j -E0dnji]i1\KoEȎvyR;!{!Z؏ ]A9 S%HZL̵Afj[4@l 'ʔJRעČl Smk\^372'e9_}ޗZ5T֜ 9p0NŗAQs@+\Ejšժ)кpn5pS0֡f[p},%PmWE\DbjkIUYū\'3wC0ѹDk! sLV+kE*(i԰.'#eF<-þ7TU['+aZ&J75mA3jN+T @ `.}ТЊMRTMG}xC;jT3nL բ1JPoj2NCY8NGpg)̀wi'G1 !0w *@vbZ[.UrZkNEKMW * K|iǢіfKNEi>5b4(<``mCnlTQ'bg+sVWƩn 1:H8T vI&LAn9ߜqtF[ "7Xv`SMP F6\5B@LIFi!!p`;Ӡ-hٷ+$fH R$0l箥+% 4VsJR(pR-дJ8VEbք@fxƢٶd5$Z't**d]DD\F$[Y ܵ6Z#%iu8a#izX0]MԒT~x9MGۋn} WpH5|Lb9h[̮>]=ևwǛ3 X^H19lHN4ټhQs),)9Y B@mhk.Eg5SVag.g|&b-0+̳weGC̵.nG3{vnk=!ځXGj`|0u()ك~zb s/ GԊbή| 2h/ceŬ.B.4Qv&o/G[/]@-EY įA.W5VG* xA7^8U[W Q Z2mխ 6eѥ` ~mF,M\'yVaC84CB@~vP|f\Z)McOxֈs50S$b䉅+֔χL/W0^XLv ig_aƴ}ʘ͝j!i7&lֺg+ZfbmFZI5М aRL ~^h(3f3 Sɕ1MOljfRMe\\,11Mdh~MRϽ˸BSʿ^N-A>_!l%V{lLZTteQ(4:U5kFhsq%Vf3rZRLs9{e%.fs ⵵2q}z\Rgv4~QY<܃Isi! ؚ^f2&@AP'0U"LMMNRkn~G4h 4ܳZ$apF ]zLZ(ouV?e -pTr1rs=>$`^ZW?fEkES-EЪ0vܞ?C)Xyo2]US!6Ll,!KIKL.]vIxnO;8•]];8-Nݭ4~ sh1D+HR JϽNYohyy*ֱ[?[a@D.\vDJAs"~fԌ< 6<)ׯ7Q%SQeYMXd0l6qRˬ38X Y+B[%U\*ĐpxYm1FM#A'\7!>r $:gbS8$C%0}*O?@IYB[ٻ-f#Ʒ5ن̖ 8a17eKQ^nBQJ6`P[[ F!W:r._WW@O}N֥3XA+Q@O­kgd QV[lXZ̔hHU 9ϭ">5*#pc!vFi``+4 MM NZ0mrϫ}w&ZJ때iH8:aQgfacMS׷T[lSZGԎ-(Pխ3ղK!v[rKgh$+Ԯ+o}#/^BA\6Ѯj Nj7Z!jʖYqǞy\qWHŷT k㨵.Zū)v,ݒiNphra_K c"<]]  vv;U33VtV [,6d,2zm aV>tOk׭<ZŶs*f.Z3WRu0uFښvD| ׵ČqU 4։`tl/ՕcTү))Cb&a΄|T$CGM_D)?N z&`rkJ3<{-KG{!K?g-l-]4$hn}`z.fW&}||B|sخ9RDR)lKPtɹjE/ W `Mu.R&X-i5G C?cu\*]̖+y⺂IbN[t5t3e 0VF8*8+E̢|v_߿yRiuI`mSIY[4L[QBIR5{:UW(w8TshT4ehYÜ ^luQ%kd-1pJBc޻ q,Us!<&h=wRK_D8WNu.lbCLjDԂʗV_Vf]qYFFM?X"-h~O^< 1kbYg<: ,iiZ긕|ߪ?4@UBۡ@:G0fjlOY.)ͨXTG=Az r,j #^ nխR&{tIDATbFCôٝ#0]6nC>Ք;e)uέlfJt8ⶌgb D۱CK\p䠽tPjw*t¥h~Zti*\N []W;1ړlGet2*uEcp؜zkG3S8NAI(r [ )@CU/.gÌlzjo)z]TiEHJ;u+Mm i'?Sɰ :,7p"N|ۋTۮTFkBJRi?R) GQ;h[hߥt`QٌTdQlj}DY>qB`˸:+2xUG57z|Yo2ER>ѯ\/7WJf #Ur]1("@q': ZCPgĐTߪW OH\#xQau|9& e.N!qC;1 sL_űitw]a4Ds\K{!&SXˆtʏU S;~ce< {ݨXYN \gBl<ޡa8jbm4٭\.ѱr a*G\= ѵ{HJ<ׇYy4\>V&L7qKg+ ;:wF2TA-"o~٫Faf1-K7,by#{P4bתְ$(_;3$!Uq1[tZh=u7(ֵ5W힧Zcꙸ]a:X4Q #uZl]I;ִrRA\ 9lÍ.+Ŭt$[4{U\+eR blth4AeLD=AJ /q0]?J- nn) kEBIs& 􉇄P=0kYTT%𝬲tatLj] Y#^ՙ] ÝjZwq1 M`0&bާlꪫPi߫OT^k>1C#(JyU@Rӝb.[\%b!p}ma0U1T5t2Uݮ,6{OuUȗǿ[hCQV8+vѕ?cyQib0QWImZM GNlMKk1qTb6o^8tG5--)?븙nӛp{v7\~Ulz:*+T v-IENDB`gift-0.2.0/testdata/dst_maximum.png000066400000000000000000001007051513354670200173210ustar00rootroot00000000000000PNG  IHDRxԅOIDATxt-Yrq̼[Zݯ鞞ΐ7 (@e`C m6)&eҴDWOO7gu[w̳j~^WU73N_U?_)@$P"PD_ ߸|ӷ柂e6^ $ @B(Z W e (QJ4*PJ~)P()}D3:|7 $<x>lBc#]0K1(H-wzH BY!hqT$AD#"z7Shԣ/N,Up?ޟ}G9 ܟ~~tt@o 8exet8_iB䇾'{<އ~?wn Bi5Xx7n=a1!iF"d3WQ=svo`) 3/~5DC .y%&d$IAQJjZBT)H? BJ==88zy6gEߵO I7D8D` %!"!A BLQ_Ό@%`"A lqBңXo{_ ԣ߼{6$N"L#k泸?_Է1I tzovUUo\ܬWW2FO/ OEF tOͫا@8(º# 4ezFǻhRfq֮C=J@F'#0& icBddHX.:BKI(TZ B$P R_.O tAZF EqGd&]c*[B'Ԩ$j_ DH1J7cs}j=|jSkw}yB_Lv4!~ej0||Gjcm+_y@{sՅJ6FW+u=GA_HZ=Dh˵n\+.On*^pwwMTUwWj<{qo0 *UAH W>IF+$'E>B.1 F|̓DTWwZޞ>zL`JfAHL ze:.AނC>E&b P HƇLjt]/h\:8 }wr0ٙNʼF]$lLW4ù~iT' mꌏ?9P x]ʌO~l2ݻwýj껾TrxRzB+t{_惄b::ƠM;?;xDnfX_w+BXiZ4*@QF1"-\-}%ѲҺ"hT%QJy$JU6U _ |ZMu21S wco/4XCdCVG>B ٖ "%G$Lc^הprrSOh6+%aZr/*#.ٳO|Uv, furuZF'?X^^.Hԣj?zm4;'8z\7FpδBiT5!hc%2BbN%# ,.=tp2m8bF_XQߠ},@I6 tńhЗ!H)"d*CEd`RdJDwTJfݵnf,Ln #/lB}|a]$!|'Om ÿS?"c5֓`Ѵ)>;(|wJ3U҄ WIy˫WUsa`:{x8Y]3oFZquO|RK4ll-أ(4=!7]!ŀ jbl~8Եъ.,(GC" FYXw\"D!^@t9nLABPh2]tQNjRDXSB"&T ?>"ڢ;z齧Wӽ])i1W2vDp77ۯ3fLf*O򣧝8 `ķ 1MQGxdh/GFR "&˟oGZL[ 0bM5fyUn3ی棺iz$ mt]qUT] YJPܙLI J!JkS]QIx"#CkUp+yF$t~zҭ AXX Yk /^B"%>.!/C Ύ泓f+ !X4RWpwwORE.Ovnq8ΏO{G)/ќ}rteG{t|9fx džgF镒ȦV͐j6*[73fb+JVm`Uw|pGlcb*p~Z4#VH'[FT50A5l6UmFJZW41"P4Q*jJOG;{{?f{Ƥ돟~hUa&G*i^8q#-g?.|%(a,: vLJblYBe2TjꪦԕoV/j۠Qia;O`/.r}b%(E%ALE;36Ĵ ∊L& V ľs'gh@ֺ WK_W+%2.>lVEL#gͲ-䬒UJ@ Ҡ@BR5* b6%dIm mMOϑ cipB2Ρbrszɇ.g\xi˱tT࣏QgP Wl-*ȿb+XژQ]"9hv^Np&8+xe^Q4ylGvŏ>6wΎ/,˜#|8"'XEGQ7 >`M*LDѥ'J!(D :9l?*kH)e1}=1)##'t)^W|$!|IL%[A.Y)b .uJ@{J}p'`w_ z/T4GgGW+!:9<;;d|HZLe3C!C$=oN"emO[q p30@8ç8켋 $`i @~ R6o 6 GžC1}fBO/fBdRG a:;Z_r=*#襑"w!y3H;Lre'2@:`M"%"z4u ګHVG`E1u6XHO.>YWY]KA LUpiH*8 ){}FTIbusp42SQ\pؚC Z݋d&S2䌷m\J]_hO3&㶔w:E t[<{Hde0;< q^D&d(UmkJ*)ʕ=x?}^{@~L+.04G꣗tS)\(DEF=zg77.1&:~f-p,T}+|7JLVUIi;S';si@NX&nO73Fyu 6M p?S".鸔=rh6lS1ꈵB6K“EHq8P C'ZZ0f41QO-b2RZ\.wJ38+*hʵ}D6BqNE+Xo֛6xL@(dxiӋ0c?NC!Z-4yE5?<=e]ɜ`6#F i6Fd*fdx-5Z5&(bQ2>ȋ|lE X12UunFf:ײc(p(_ꇉ̉L` 0 Aj-@Gۙ8zZ4Հ! qk%iRE2>b!Aav)O$ W"#.D:Zˉ#C z;p퉅$8/9JTm:fq~#ׇ|ߜ fbdXa(iLH]fZÝa=j$2EpdhIA DhX7q;OAJ) zxGZʊ6` dfqh&$:ty3X`bb\ N)smfcʨ`r!{ri1ȸ㴝mrƅI.79gو0 ª[NjhZd|>fd;n:8`t^AHStB!뭉"ףѽG2CT$|P!Z2 [tULu i8 CLSB'xZk#1*;FaWd%㸅7Z[Z)Z`Scֶ2=S i $(bVd| L7[@,]FJWJ[d+!NJV9+NĹf*"߀H@)nf,l5||lzAG!֋+-DGqLk AёST@1N޽wv"V'D*\ v0(D&eIV2o~jG~"j@1F(35!CʊjX3Mz[a,'N=INӓXk!l d7<Ⱦ)9Mne-=BjxvL1fu[dHU"xΚsb^dTו%Y@̈RXΡGRo:H7Rv@[%'Wewn>5L"8a_PAWϻŵX9,(RVhz uuAFPÂ&$LYwq )6*d젹#)B _xs@"pCRROXbl0dckᜡY"UUK(텐_/BN61\ cQpFPLm!W Iddh \%BS(pPtOH@X #d_hQá7r&(ab#:JZ"Cee[C`RI9G@tQd|XFUsaMX=@{Gǖ&̰et*E|GCDs&\$9΁eJƆnݝMf|؝\Euƅ#G8j|0rNs!%0[ ߭s)_ʌ@h1ڠ@c\C6Ihbߛ}A!"/LOl|3 jsXjt%YӤYw8t73Tޞ)漜,0 ! G1tNIL[nQɪe¼P$w_A`sP$lE~Mi%>y: $*e!dTS 2sDL0 AZEF!Pt ~)7=)*d03K|s( >xNI~{NQb1 `34'̵CDNh2@Oq)'),[dFZ(Q)VmZovtY#bFh#] }˜Z6/5#w0];7OfI SSu(A7P4+%R+*\/JWO&Zv3bCȨqrn) )h:Y~LW;ßŧ?MDb?f=fyeDL/?s)z =:۰Ё|S1Q %˳ƃ$&!#o=4PDqx) Chdx+bPcnD 'Ӏ 7ՍW:VzzԱL,93zu`nA՜nW)Hs=hEHw߅ˋC8OUdgS8D+Km^&>Pb6>0u#'vޓXl O_byvuŧ?2>U$7$N->R.e_MPEP/1xΒBЕ) ,+@Hq=RHY#R%9[D0C-ͦHp}+1̗1@@\q- U<n%EIRlEh&/쐔29D&%|)9{Y,a 3k j]<кvⵆׅK!yYR&|i%9d3E '-AJ18T}N@(*S?1P koz?SI/BwY[ f4ݐffݯ,P 93E1 &b' =Ƚȥ;z@)uVO{Tcn ֭o-| qqH&0FydCT7;8#$'pR`/+r_K4[${_{CG UF{#d)ʟO\a_ZW-2Ʋ, nN>Hv=Yȯ c xv M߇}q'T>zj4J!dˋ'kr ,>(c.+%1\KB %-Qt3sI4TjY_TZs"Kd!,2r䖔_vR.%Rء ):8y\,ne`bB/ۋfW3pάɽ5=vٳge]pc^O|=RaBF۶gw1Zgd}ȹ+3d%(SJ!#Z(nӖm2`,n`ιˋ9iAJmh. =7,$Sé, T_!xBoCv\?}wL0Jbǿ|uXۂZM*!E|l#%!y)w( ./ M!g1 ,6M>-6 H* a!LC%L0d]" Vq6Ԩ iZe_"$Do!JWC1*ղRIB2o,vd]\2T 9)Hqy~?^8|M\ Fz| QYb1r!oo;z~~w҅h[)1 0P[Ge\Gg,!qv$=Q(rO%(Bc|gUF|2> Yܙo1?sg[a!sfqm#?nvqOxdmrr>bv( o7qѵexXJQH68rIgEyd.We=WͶO`OpB9$J'O_?iibtkV]b d$p'}4Yt&&oY'v;CWqb/uz *Dʈ x6 e@"`IҪr9A[>d 8:@.˫b%(m}UcFb0)`LQ@%UCW>8 =Ap>Nt-MN]<~rqI({.  _t>~Ǯm4rQOASp\{!Moir}|dQ:S#쿋:"kD`="k rBRXR[| PYJ~3iM5jNr"=rF(7XN:ط[Rxk'Jfn!9gPva @n!j$)d cH1~)H*A6,6fY.C-mVOPhή?@(F"'52'jW \?{Gx>Y-ߙWZ{z]^ccJ,5CN"_7s6&~!Cl鼷d̳V(k@n6l{p4 2VS}`TؑtF;ؤA@q[-[s)ٌɿhٹkAp! p!FK԰ D)p!zrFpq+NV??%(/hLwɨjLԺ27z6]c*~vEB@(sG5rP:acʊ0<\.e1"OQWa9Y_^b'wbiqvp+(36sdZH[D=ޑAHLNB>RXa({GId[>M{s j_4w:;Xi3scrz!ֺֺ85vӬ4 ,zijʔӖxI< E6(͝[O[v1| ضpx9: PJGJ>;T%#˰D)jK)s nKޅx* (CEoI}(N6.}dQW.1^}y%w0-2%sp(1$P4_2J}^M9D!j[;(q )"rg; 8S)ncDQIn B  ƥ=E,w9WBrZ&j9]-OQe(:f{A M/cHpK8㓷xϢ$+֬*n{7B;)N iDFHFW<@$T_13J);sW2{☢c*`R40@1r^"rc 8C*%w)pXYv:,|e,sJp'OSq#EK[6YRHޤqzׂ]CiQ>n>E؛Ԛlzr("x/5 X 62=F{WcmVΦ$5Td,bJ2m *i#Y=k #P^A`iU(YU)QR'N2FvYD{~eH  Kӏ(bIpJ9R eXAɗ)6=qA_'l$w冒,5O9-HXXG 6h2JX1a4xbtڮ*3SP0z}=Un`:7?;@)GEV'1ˑK3-QqOq\C-"/~U6Zɝ˥P8g^y_ Y!yFFkc_oD#ZܵD|Ol[v~|7畺.2>wڧ-_22wUΕiظp)K&0FVtΠslnj]ed8b6kd}4,s :z)[)cv+1@A,XI6*m8G!BC's>{ , r)xt@N&\V! ЖEaro*ݏ`ABrOـ!1vn>Z%Aam cL{򽿞vwzmM_>{$B Q+O(u!z)T& _"pu+-hn98^;Cj}kz׆+ H*4pJr rBmwURVekQLWkWA>f kkp q 30 9L%w|9B[ƑLiU};gʉɏfBxtVF5f$:CJfuo:pMNy뜋!w-FGBIk@BҺڸ4};DX7}+\_skoϑ_ϔFkn\i2u(q۵>:uEuN{= V 0XWPբLo2qVs>(Y f,($aͳɟ>R`U{9ÞbZp& 폏tO=A9<LyX˴3HC,tc',c!%br0Br{JI%C'7k6H .ɩV\] F4I\tnR9iji**Qo_)`2ë? /-||A80dc.`f 뛓KY⋁SB}y$Y]ۛ}BJ{<3 /7˼բP'J^ܙMNψD$cӄ6հ`T5(MFbk(1\_brs2 DR6TU |͗Ń8KzI_|c꺮s_\~#6 n7Z &ĉWEj*F6}\=FnL=nm^^>+ZRSsp4KKmHjVVA+DȸǴ|o Kp߼W[tS{6>m|G5)k hxZ 9Q&g!yCesJ7EL%ᕊ]k.b$)9u/k¹ -1BUWXBĩAnDxч4"!~ugKP27D_#~.>n[∔!!n ]El:YJa|W}|{ovAe <_,0B'>lN>a]Qg3><02 @PJBɣK_EFĽ)^.Ͽ 𧽻~N?\"dpQX߻Dߥ`))S}~ö|TB@oҐ1dy{n #|$d`v錪@nσ G'k6Ļc.nyꠍD/wwG߂j#6j"ҞІ wW5v7j~\G=t˫ sI_MI];1Tf>87gR`O&!*G8tġ6ZE1J!e{+tҋoΧ3cD{F\|R &C@FI/\$г~Iu!Zg㉪Ri[mX/U#M[gOߊ6Yk}$5F.#?iS|Іvη[g{m^$U2(5p+*.'h!%`Q;M&/p ^.9G a -[/e.B,+Q|LT=v@xK vrx <ҼY/NOG;(薿!EɆ@nl" YKK1NEȈ!{ i _uHo`z" !Gz"L༈ V||ݏvbTSinN|_>|;[}zɕv y@j(@*L婷.23d SnGYi`S" T/CF[AP< ` A}E_ExȠPR& MGԚߺV(!8= `o}m km}cjG?W;wzcbSdIJ([icl/0xa X0ЀrC[ܠdwS%D*x̌o88E[;x,Vw_̈ߙ~օ8.:5,aj̋Dh@OD]Dݡ §kj\ oվ?Ȫ4;)M.SbQj3Ov<]%$z? 5 :"~>şɟ [~ɻ͞&7ۃ?a_~~m N!HSR_)ar+'SЅ@?终%p}ׯ䥱Q7|{o#ƭH#a9vMϤcZ>b,2+k{9)Ddw8hr>H?2rr)6q1" 1PWLFX =yGNlΣhːi'Z責YkIlk58L v㔈>KkvAz /9w[{BnC"ykʬp/ߴtXk#q,JV`\iamLur.LM$JNd8rD;Mw>ۉ>@G0 / ?|^I}}]{-4s20 =>.-7.˞m#B+b'>v5`iW\{ݐuƘg5|M[=(\ aV[@\0C41;6zڨV_K??]3 ?v߅]Ka[ʤUj⇰;8{Js?@ІJ\ $KZ b6^jY+G~ԩCٽEMJ;t^|n}>Z)\nvW; EӔo~&3-`k{eZr;'J_Tt݌e'w[nyž|EM]ȀZCd\߄aWүE~(M%WkWqwGS mADۿ$z3fԩ_HX_h-P%D}CdIDsV"b֗jݴbLdo(@ %bB{ ؅|J B=&h&P9e ZkKj.|OjVQ%]G25YR.{H5aC!\|Ֆ=^|L'C: ]7ń@$ *\pVz.dJ(v s-Z*~"E~㯿C#27Զ'I'rRrsxv Cal)}Qkd1K T\}z|p%43urP!I >4DzjDo*d7^3ESk"ھW=T"߉[JoCR;O-__l6M:$=$u1zh5}ޭlݕ\mp> A '41`D!+*RcbuEVȰSemŇ?^]X||;t='3]>]7BIӦΚ2 [ - I>?QUg d=1 WOg Iz>}}MwMKGKi3gDyw}Qeyw}ï8Z hT!m$aLV?En"1S2?6&["#ͽBgtǣu hol ʽ4:Q6]i{IgߓҼ/eYJc)C\v9喆{MO*yyv'y6qBd xsr.FԘj:!.i y8Ŝ묇WM۴MOsMhw~t|?_Fh矗l%Ǐn]zRK ܚѶ?&d:)!fG e#Duk/:{xH* ̦=Ξ"` y6q V `sBG$vwߺ={|n"zzt{_~n!>fLk-Gq)oHqg{c>,dO-HOb Z@GcZy~.vWQkY*}A*7>8y f,j9c4 ɒF5?m?{,(-"a,>^ݾ|>qXC>U}""жwLey}cq1tH S52jn篶 )[5d`ĹcWޟ -2+ߺ ˛sŏ}$rk1R.VQ+xSS͆v^G;#AYO &3&e {yR՞EKPE3+j&f8+VP +1ǸDC%h"z+Ջow=G_o/zI>#y-z͗ğ qs(i|ܾ?2WxG#AM 7D}Dy1 2] ɂhpkzGk˜;:5]yX.WE_?;/SD|<7}W]4v3jJZ :#˞ Q,0֔mL {?Wr_1r/?Y; *̹N1[,bi)fOSx_[u_6ߙ#]gļF?lFLO->f> ~،l e& 1.uwļ.6+̀l3ӂпlHn?sƥ,v1PZqcz Jzc ]`ܝ{LS7lO;RAG^y9>#t9K; n6AL.u%cLےJC!>-"Aq\?NuѶĥ:%̉7aDM.0DL2Bܚ'%2pk ΰiRkG!˿5n8ER2[$4ĖRpɏQr[sW=:&tqnpKkDJ`*k+f6̎QFj$Nj=-@b ͥ=@\5J&Y]n6:DRL[ٱ2cB[,3v[3RYBOܒ-!MB(x?N,#du.VޜZc( !2ćD_lJi,2-2-{ :Ot,AA9ݖ<9 6o А1cCQ#yd^ߐ unfh]:V8! 1BL02LJkE£'7ǕE\e0Npګbja|@̵0YCZl5 O/pꞄ"hJn"Sif{<L ヴULv(&V 4:DNɌjI3"c~$@t~Ҧѐ6qH\HE&ƇM5roGazA ߲_=q,-wuPx\M/mk葑y:Nt8\ǛW_ypYKtXWlS۬2zkZ̵e da^UV)И Gx8GPp;&鼞yUn1%U`_Ysγ8UxrcH99> wb m̘MŴ`mZƪ#mɅ0nw!jkehvNU{U5"x t hiу 'rbNtՕ(SxzӦ%ԖۜǙxcYr-y xfp_tID,%es>,0c+wؒ,>aßp[ZVMwd#``M02@\ssmq64Υ::/e>NxO1/UjcnzG7,*!TLI`PD|@i%!1mJ+W18!NŵPV;nh IzO(!$&贂k#?&%j ?0DWP4G|61Cw4@ҽm>N^r@"nn#{QJI I]Y|yiwwGMRrfɄ=Zy, -q\뒗9g=h!mz-05KV?$0ȃ'޷ !c1A2֜.tA|!i3N: 71e_wA-?b(:>Yܯ_&W."lD 4[ѨuL<ѸpuYj˒4OoẗY7Z B8U ,G6!W5V@MG>([L-7J ZG-c*gF}nRP"`Vΰ~iƉuL[1̉^ZWkBڡ4-׶ʜt(>"EH Փ7ɓmMz}82٢hTꞾaM| Ik`ExKz1s!:0Ms^jY׼0pYpzG'Xl*Egg*fDžBWS5W 74>0ум!;:KKޤIAh|Kn)Ez>!%w8܌[gb&ʑdJ+ޅ eܹ>2&۽CGW#*F+"Nk|-Z3nu(+Ĺӧ&ZZR6hZ i|nw|y9Whu7,8i =zum Ҡ TpsGS XD՚)!cQ{ׅYdp$u'P d~xH ];aQ⿾]לL1RiBbqq4D #@|@U*Zm$b:Vi  VŜzcc 4'P{ću /0}* WΌO-LV3zֵ N|/xWJS-&:̯ɸZau.&WpWb<3i#u_>$AAX#e*S٘v_Vx^OH&zdTGFj#Ɯ+ "r^f3hʝfIfC`*bWEEYBK"9#*aZ~&tOѐȠr)]=abEa;_u,A7r!.w[Z.lEmP*iinwv%4N0:+=,+^#bBp $~h;j^sڐFSO4Bfƒ_j:` sMydPL:7C~0%,L]s QtzP+P? `Hnܴ'A 4rz ul DGxMTV٠۫'O_8v?OO-2{wX~";KS)'Y1 5]ݰĘ+]IjaqoЉ[l&^kao',-@v^kP("!2|"QcɏaaH1Vq&Yl徎'Ҝb#0Ҍ ^Yh]?Z߆ ˱ Bl\-AՐMl7wA<쀉f(4,޾}l3i:Uj Ȏ4b/Pya>^Owr݌+aњl%yH@zz2VRHNFT.dLmPS>n6HdwV쥌13VX Jj WGjDj/def\ߪs>!qiMøy葞&!Q7H~8˔M EriK]n42lae:8o *սH !7LhJC|Pa }5.K ڑ(>IM \h=3h:N#rFa #i 42>HwRg[1V'b&ѹMk*bAZ; {BśYLTذ>x44m[ h芪ߧ@JKis|TVQ-P@2jP Eݻ_aovji`s뷓/\(aӑ.|0N{$:WI$%m4踕 ]""%Zؒ48' 1&?&}H(84ӳT*`ă+*2XQLe MV#93;L#jd)gl(6Dv 'v)]QW6Y5psv.߀N`R#@gyTkV¢u5ZV2OenF tБVUd*@$&&#{_/鰁3mt,3K*|6ST2owUQj3# -iAct{܀ ӘЪ"0BDW"ô= >PfX8mcYa⊴ NdN!n"꓋і muIS\ "p1L)Ih6gDMV{  ::>^XM_i =NAӊ킓94LnYZEP38|cqN-ӢtD?XҪ*5DnW{!7 &Iz6Ҫ"R׸ʥe8-<-GMܔǽ CCBO̟հy٣ݒ )6h6 L1>!Y2 @z*A}p.Aw iOz}iI'u[lT*"l285tk9ryimLh2ȭ,f=,4Wkkݿ=bj+GqokLܸ=f{尰if!]8vt~~EW"wg7w°+(CGksj޽hFGqyd煀;5VȀ ?h@,ဿ)vlmg0}`Kpfhoc pnpP  D#-42p`bŐ^B[p[%Ԟ (r0kZiU+qZUUJT G^{@Do$ZZ{MD/*WwӜ6nf+3݃0sk6Zd8q;pP!78x#Àх䆈m8"C=Ư*] gu(BCȈFHCf]Ѐ"quA,@EX=%مE=* Tdzwn`V.10igȧꑅ#j}o>٨VmZշmvΗi!GךG=V1ACDEJh6"@^q2޶~Re*++qۦO7^R ۆ $x־ʚ]CV;|zKfWu=~~CÆ"c~KWC+5>;Ozh:M}WqZT|ai ÄC!F|lڈs4kL=aX=YZk+\m Bh$@7V8@|Z8ђ]AعZSK&

؝mD[UF>iBm_(m9B[m#_Z~DI!=c H)>Z|Im})D:zMN IAQ3ȒsGEU͌USD/C_GS>hI YD"m*5SLT% 0=7WBG0j7[$aˬ*#%iVsDӹZ|"-Ps5.|kc#2gr_z|6іonVc:HH9a蠮<է&B[#zr!Ĉ1BU6KӴ!ipF:GֈƦC3I9!ۈ*)"ѐS^tLځ-% Hl1ZdŇɂ:*[݊?@eJvYhF؜Vr >_Z4\'=1w9Xl@A"j̥\!ޚS^@˳<,V4S[  ZDŝ6YX`S? ׏ \`ڡ cAh9z)Ŋp{t9 ݠh1jԴjB MG_( wt"CIXo) v$xPdHXY\#c5Vܚ.ES ֊Uг]cA fH&^X؄>o.G|GNl&p@-?hZgYV.?Ռfo96KKijKkB)I(kWcOAqL5km8G ndNjwts{?11,Vzk 9[5CUVm-pHag!`?b`긶2 p%I]L9j>4A$lmyo"$r~鵀(dӪKv;RzwkO붎9ؤNpJ3AM2]ڸ.NNr.Kl2n=ͨ+3+)hB'EJ`P+&80]o}j@ދ-Jǝ VrY(ߕ->O*|cj/SM$l&ߥi ^πMڔ·GzLX>Tc뉽`IDATƛDIn'ߑĄ M%DBq>T0F0vSd`">5)bN5ե,SdؗZ#rV_C) b Q|"tYXkB}^u:VQfS%LEIV#k} Sd)X'AX8=U}FYN$kTt*}]_^>28wf*A0ǯm5xUo9'@cr:71lw/X$Pβwy9>n^\\f R32 69i{m4w{˖[A[qLP`gM83P\!sU 8tv k GȰK9NIENDB`gift-0.2.0/testdata/dst_mean.png000066400000000000000000000666441513354670200166010ustar00rootroot00000000000000PNG  IHDRxԅOmkIDATxly$I-#"ݟ$</AC ͽwz*XH F3QvvVVVd<" TDPPD EWhH(%-̅QPY%P!HPT #}O?~~)?yfaQCE۷zUYB[rj?? 0M_?~|/?z[^DÏ|go~_p{)βܤw(r?ۜ\G_~z}/y)R?{EFº}ڄ2 3 va SH><\C3u[؟ŌƖX="ȶ~iK@33W{>?zPE>' f`?޵b}v`{mY+BʚsnixO >&N$pt4iZshF|u.Rs>>,,˺,˺,z]_ё? )-`{k⁈0C$Uoԗ#4N9Τ0)D < .;L$> FDztr ض~PXY:{^?m0>o?wc}z2JFUO4"C*4=!tؿ"nl}@9껮ŁPҺtޏ0y.WQ 8 &Ki(q PW8=???;蚖J<_Q. quޠpDBкntQ0 qT =8 (J. Cf`( 2LJ|Հ.R +2Bwh^ˑ}o ܱ80"Zr&O9Fz*]OOӓ&]˷"<)]_r^)$yYΐJ7誓kHԣ#,l8(z=dt.q8=akIx{W%- u+{9-벮kaxp/Ү:(pd( mCGݘ꺜9yUfK_{nC O>ixt.THpBO^ #}@^s7;ȧr%6GPpIU(%ϯ;i8ݖY{5ՓXy*ZBaaiœXޯ|s}$"XKYpTp^| IjT,RG֎}@?G? +27Zng*쵂20˒|Η!4Nz.0"F*SL +RT*_s]ޛ!eȃiHm{-yp}XsRajSG QG;x ]6w,8YFx}uJqKͷ0yu-J))z^=y{8$' q1E"__~˲ gS\#Hp ^s|=_fB > 𧏟N??zPDu% 9>ka.rl0iJ@:x?NHa9SʔdnOpD7Q|]Gwv cm-;Sj8My'RkT]2Iε1 #6u{fp6 m[Fݷ5_uE:GsIk=q8>=}̷5Tr0X Hn/Ar>¼ner=/Rs " I H.sbi,(~\?ӇOONeJ<%>͙ 5k2br~8>F  yJJ9\y,qT?Q0T!;rOivd.a4MbY8=;(J:5Ly&hjC]`Q_މsXʚSfO:.7B N]+к^/ko7u@:>*5vpX#EW}\$B?pp<}uQ IR\ִ2)BX!"CNcGcvr))%ae_p`BN)8?az ܁c[vӎ`q8OqiI%\r2q*oOɤ PWv@n^CM{{ÊȰ[PLHv'%q<8n̢pt iIyeIYK߮7W!nc/(olnOhF[UR[RഽД8 uK\/X=7W31f58L~i:1<ϗ|~}眲6ٓw ڀa.H-3p@Yfrrz#ebn`̥3j^53fv-Ҝ9k( ꊺ##"՗9T1K.5ĭՕN@7)4)(#k5'v5|Ƕ۱=cZ݉N.aψ)TpEy3f1[~9x =\q :p88ÇG2^+,7`;ǖne+Iܓ@Ki˒:+|IJ 4^ZNm_U8k)TԫsٿJTer-g/*=$@b@PIɂ8pXs-ZŭfgN^XX ]U+*#ahOTmчM{Ə\837w죙h;[J0wCj` T5`u@ % B־vz]JdCLivQ<U31o[^H6`L4NkJ-rQ 0Tˠctf}s`FՉ݊[;fe;=(b q7Q_~ڢp? Z,p8ǡ:}kME yN|6h~@yvh<œ]ĥ^oGsn{-|U';èaWl|ǖ}nK,*f.X &E+a8 O8|E8Ue3/v^<竃=i]@h%2Re[q|z yl9C1 v̥+$8"ѪN>#'V}p8<=J)1+_t*ʿfcm!xԮKh8~2YF WQِv㐻}Ti(ؙAf:FNJ:aG(Z%:_˲j.{fkU.IKmB\;rNFL$GDLjS:5srlu.mߘSn-Bx#`! A7ADr0/V _m9&8j9چ&b-i[I,.)%"f6֡0#GZ.Z[AG.=!xH?8+ط X <0IZVmF=220LT{yD1aG[ʲRuʅF'+]n E `aT1at%vT,~b{}J9!Nv:I[|<8%hSel{'iu#!ZɛJ.kIϮ}مm;t f7 I߽Iʼnh: mAV!kZP*-cnGcI sXz`UM5CWr˒y|18;Zm^6PׂzG YEC,&B,R<ː2a2U(%W:E[ג VE*[e4CAC؊N4wN{޴PT=0ݽt w5keaWpa5pxꞘ5l[͹I@ 5s*e*(挸kk*KKd~[T KF7aG!W=>s!8/ \L08 xtÞ*alɚRr˭ʶQwl/zRvhAh㑇>c ;tw<#DqцDqydYN*g|(5{JP*f^ /C89-zj-<[?mH5MJ85?[wNnJZ < Htqn J6 V6Ɵ¨%-.@OC p0vOD0왩"ee@dmW!rOm&xl]p1]<ܠwhjyw^wcڳ'uꞈtZ 8@ěqhgm2{E|I--V"%IVԏ}MبPI"G$1뺤^O~x#9Du5Kl>wX^RJJ1i<0_Cz.غ4j!njOTԠDJg#ZJ1J<͵.hz/v[o5FؼJu+TL:M븳VPYqZ, {Q">Rx.Fٚ8OECnm]fmDCrMw'թ`H`a+In*3a)Wڡ70R-ûkb:Mt,Zm'C x1Ӛ|ܼHҲ,e^n!VUc3 kp1 KsM-WleTeⷔQ`lؖؾHa#j-yD&BDkJq(1[ش 9:ջUmV.@g/`wQpg8xA,kP-TAɺ..fb, VܠÞ^+V0JP9w!8ڝxxY'-䋤VYIky?߮~}ۯS0|<j Zߕ1BK B-P&fXM35HMb]+@mM7m $V}H ΋XdY/nu7Vԃ܇,d;r ~%VM~D&PQX,R=@cl+e˭:t{)r\/<_U7tK^sZ2Hi-3m2}y8L;K_oo(v"NRRn:{;ʦjDŽ<ʉݦt&;^Q=XGw|ЇLNH :vh*Qwth^f1lU]^9Yna/֌l{P|\]:;<Jt/htڦDWX=aZ3+P5-[{$|!t)>Xj2%0j8Y2#g,5x@_q#6pH^\xED#*ue1zwt'P?: VLcOW)\*W_5ئmƹbɻW7ˀMܞ`D| a/Xm!z+of(fػ`P{M) nM-2wC=6s 6@5-ف@%d\ԥ^mEVk,h00#K慵8w֗Ԝl :_%7-LE]5\$^Dye&_c6I$ o_# |}g1L]|羦M{ Q-6̦GGX9\95hdu5oVv}go(ҴBQ$޹h7X֯E'VhE9$I%fk+kTwgZwFכR )yZ)DP,ªĕ T]5~dL%d1ebf+ά=_Mz/[`l%4`CSy`*֩Z2NO7Uuhِ6mw~B4o?<{6ٛ*+,(T@Dr[OM\@\5 f%Np8MSFu5z^iv-[pR;C.n?hҳsӝ ^Uє- ִ-Vi|/v.PhI!SdkKV(h?ٔ&}na=vm¬݇º8A1xG̓Ոߌ k2Iɛ&8U_cE%_we.;VZ.ښ@q?V[u`rQcpdmU ʕo z3RxSɴ= c])<eN6MwXJUpΩ8+UpkPXM[iuN!k4K2;Z&g>Ts,>8c@AɱmIac%Z `/rj ӚgTۛ΁S00m2u-ʼnW'RMnJ( ȺNҬvyVo%F$C%D`?QH,%S(M҈5h>ӜsFq{@IeIHmf]G R J^oh4d.)洃BOLm*Kɛn=4wFG׈b-\BLk:pV !!}~}R^#Qg?=HȮDnTN- JKy <9mN!qϺnosSd6J%'`!SP#ۜ =z1TɩP. >aů3`5У"F;?& kΚYTs{ˇZ3zO,yϣ#FRv,d9xoZ+gpɮ >y| /e>w xHO'So(Ub3#th']Df2vb̓Gnk2Mv]~@B_hPSp<7ٝ(Ap٭"*y]O6SF6mi*w):hf+{G Zn-b1PpQXKΩr%ŭ,\rYm’kL4E-=pOU&dN'Ҍm'77{k~C^t+Y-|⟞ץB?Bhx#}9d̢rO'NFE,;A0ҍ’AbЀ@VR@HN<)7l]n3ށ\4E@c8Ecxixfަ5Jn$F|"*67sNWDq+ 1 IR׭Qo_Vhfp|^7յH #tQzʬ4>I5j! Qv-oˋ⎈u&}B`o_E~ _+]/0$86KvD{`dur%MPRBc߳Ra8<@f@)^F^|s%4i $E-sa]z䴢p+|SJ%VX [Ras6b^{OJIkRHRCZhN8vg4LE+a5i`(1!2+\8a?ө//[Zniuz)rE2>7[{c^k4ao^W7HBi{;sػҡ^H&UDn/ ke1GS ;jMmQ֔S|pS^ox$m}}v=s^\ u D?D0 ~v}~/6)%XGB7Kn$>L;̎l [(k+  -\4_ G=}? /뗿o)B^kϹ0-n%sMv䵭r%lek6'ަbv^|tς;ՐV%eIWX +]ERuh8tFc2`>rVy/k.|*Xdz>WIyo/̕Em)M:a65pa!5|I~JI{鯭5AϚU^8_E\ sr6}Q7_Vā'ʨ_/L֟u Oa dp)BZFfQ-#jڸl^{[I1y:խ/%1]쳾MWm5˨Z8gㆩ̫d&,%/p+Zw^u|Ѣq2E W+o|K0DeyN*˷n&)-n/\=S[Kk`u#m&N]8i oT$?-n)l9}8(K27ä,(K7WZ9guo7MOʯ_?OiO5(!:fĥ)qjHI7 !fMf8ҦZ%` qt/Ì7s Wb9({p !Xcp5GȟT2ϗ^'W㫯{ Z$2]rpP={gC{.s)3m4}@]GC8p<^^ot6N$6FWg 6הv-M +]Vty::Q-䑠,9J!'p[0oߖ_|Oaxx>MNryZ:U%'A~/t9tEOp:ƧpZ!^ VeͰe E\xr8H:Ujev$C o_"-k\Hx0x88{RȥjwhQ7ݑ)"[껚7!>ʻ 6uX^Q sj~jyΕ2VkjjΨ wӡ0mx?^# qă!ϢXôyK:ʇ'$ /E/*eaE<~(JVΏ:H <1VKTZߦGkTk*-A *\# AD'#Wh!q HEd9s YalsiP?)9=?tAq9nLb)֭ix.\Uo:⮞ն9Oeo0l}7mκV:/Y^ISDfFl=08|t?w?iw3[Xo$+kȎ^.dx"0/kfwI}k?f}o%ۤy岝.@p<E>~4 O ' ~/q'T~WyL+|ߎzn#dLWMFX}?⃘Ӆ @#E M ZdkB@нj/I4ؔ45j$Q MO^ \i$AiS*>|ȟ~Zq>=Vn2/eI5jw¶I:ը=MGPzB0KYLUn:Z w5*XzCQ4KA O>ar:9ӿ+ªM1|djgL}sέ-o,BM6LޘW*ao)~?L ٚ;a ˢ CJ٫x.K{yN0/\?VZbZ 6%Sײަ0S2=ko=A8&!X>|O/VעE\bWjv,~YGbطAV->lCtwsh#InrL{A)̍7̉nV o euA?3~AL="1 >i7/*z5ϫ$iGjXj"j77ު@;k&1&k#iJkC6ϥ渵f22).6o֛a2VFLB\ ɹ,$X\_^&kv8O[s6:n-%цi#_qo~3^=M+&)\R +sF9}^>/kc:g?&piDZl tOpp%_ >Al iM 1 kR œK6NgTtmEZufθ/#~.GDb;2@%ߪ}Q1)6g3nwV+;I`v9GWׂNa=}_}-40~at8$ kc a4F?R4ލs97XWOUb,/Z)=։km{'!~WBޕwi&"Wc[,poǁ{C&Z,GmSU:9Ғ|ͯb-55}Ii.ΕmkW'#7w.nc7 %'Do}$v/&YhLl՝5:Z痷%?4ɧO)ܒ^⤿&ry \p>R"ktkeF낰!$G&wK#tjX޵ ."XvS e0tc˝m6ë-} }vK ]5TgIJ*̉4)nơE Ӝ%/z[4^kBE%x)X~C[V!O7`i, lea+htCݷ!f1nWk&2OŹ>Ctc><__>-G-ߖ2-0Pߘ-3stfՈYG1+*b&^H|GxL>xeU}zk1>V$ftm .ݧ?-}$)+d<m BK^n\.\)X<2ˑ 6OH7nmg[Cχ`TSS]v@ݶ,"y)!_>(뗗\z XmtkJuIKYZ=no}iei\,)l!1= ]_A>ϨSm⎭{v׋~GKֿPzXsHJX8qM@FXߩUCg`)o. ̓nj0܈yב|jRxV:%syʇHC+c~~8vJDǙAP~P;0n/ -u6W[F~~&aN6E*|R=Xn^Lj ݨk﯏oP\VL _2x|=D4b͐ī5WǑz(&5U)ŽlбRa؉X4CvvJ=ʲEx;?a-q8Ob1!l =CNFuy[[ZkgtckZt CԫTM<Qad@hp!v/oǏ_u@c>EJ=/>~ xV"!z.~Uku ]%8a\oQ(C ]Hhrw^fխȳ󩞎J+-k%άTSK(4/V%AJpȚ̉z`I4db%;f-6zSᯕ'>tB2 ).kڶܡRYZ#EgNt_/b%+\Ÿ;k,Ie%ХWM!E:FaPh&_T[/a0R >ߟ[3RΩQq u} )S$EPK)-W\rZJ̷|/:µn!~yi8-8tv5֔ LoM71eAXHj!;71j+~w$v7 mɮhJ]J EVqŷ_?(&>}+_Ly |pH5d&: t<#⼓Rt$*a/c^Y7wĜqq|}<>~OG`aIiK˶>^j\*(s))3ە>¯he.﷗*!oBBj[{kp>+f2]1EZa(HU($8x,8)V^++1PD6|_+3cK^x\$qȝTg StiM %,E6 {K7  by|~8 'j~aMw*qUĚ!uX}|yR "[)%ei_z$)$U ~ab*`xӭKqM'cM܋8m:'JOz_nq`-ˋU*x"Fz=aUk}mNb/wpN(b0y}/EvEW^2Y@*P E[Ԣ juiȲeV=-׃ni%cޣEaAhI u#x#th4}sL;95:CaBN$y7N mpF Ht~ƿ!P`_1/(]oo>&i^lrNlvC{}5E ユ%}_uRXulA&~/iIkKz[H+i-c'DieH9@L)?_ǒcsk\"H 2XyA2|J)]Jϲp>wqy8&,'$ g $3^'eA;D [q_Q\tWzHg+Lu-0rLLVa)3ɳ1=בR3#/22jThlnҢ J2"CRQ^eҺ2U`DY,q]dT8.dn].Ak!7sn?%@W~j舖 ʰ:m},׮Ͼ58)OJ^\,JҊP*棕 xΗkK̖Tqr.1azIeyoEZ[wgJPN Հ$[SI*m#A1ڻѶ(2InC7$(m8[[&x FsIx@)] QA/),}u0Tx+]n嫖 m l52,~l,LNP|r>"- )b\??ooiYD TTXr_^_oۏ[/az8X(qZhb+R E7a8XkLʡGkMڄxpoTiҹ mlycsDRO?V\o!!#1Һʉ!bv m&~mL ` ێ6?iT 0=429K!G>%q b(+AlkN\4]hp3seI-x->] a*QDD[R %Abhw>1-i]뒔Bl [*]c֟xYH%JS`Q>A88D] 1@c ear\`mBDLJ5X_7nEFJJ}hAR5ֺ:cg1!>Q(#+&xd tC譳6um8/ӲҶ`{1T%K{fA)ȶH }ui: #h 6#\"xKĘDTTM<oįⶄE޼vzRI(Q DbYAVUCpLR4fP3PŊ[@9 M_:ŷ>  8&ȇ|9@mqփk yyU z]/d`Hͱ'Ǝ,Ol p͌jwW$,]J<yi ~=Kъff)g&D.:0V^4[=E|"OxHx?.ǬĨ%~~m ||U)G63V"g^4caY:vL:lfvN̒5|fPy/X͆i 0avǞ{|$+I).z#&)څr=vd.h"CeCҍ<]]=#mlQLWlct2i 7t[ W>NV7H$N"dd`Ld>`a"qL,w3] TMRag[o +R#`͕D$`PBx}#N!2(>)cU~eI%=}"HWMz:Uaecd,u5}}nU#>Лf&x:ilf2O:5*-H0-WI٭d:þ(0*xR + ~A/2V2 (8LmW v HB :]\B_n/~K1g@qRR?~d?HFE|B9'u1,ȕx,`\5I A][M1&Փ*55GF``*JYT/YhX8S#?àI ɮWS9okf3#Ktw O7$=p4B˶mz{-veB-)S.YМ/Džih1Rp8Yx,S,Ujz$}h!0jWm1M'`9rO`f]?ֆA$" Т!lMg@68PgÏ@çkq"wA!3@O^׃ PZ O7|Q`+(:2> C+<$u^_^o˶0QqF)_9gPfpu[1 4ub*h8d bz4,s[=l"?taT&E%r+"#),@G52$R0E%uFAp:hcıB&1c ˧$flץ} uS-nW j umm=)أܷ$r~gTBTO^H(Ő৯,溺/B'vjf4`WQ'yUbjlxbr?Q2Ԑ5{Dp7}>q4u yN-mf H'c$дHj+;iq%2X02J w!AH.ZbK$ޘR :Bzg0 Hn c7Q J[a֎e'Ow:.Klx6|!DzYdW$vfWKϮ[MV?q_8Uj?+ ֦R.>a5` Rx*2fՀmhB|+ EbAƴU< zdgNx݄#37 E%ix¨L: -5{2Fv (9 j V][/YN{G$yûTgR!.˲.ą]{WɻDzkiW]ZFtݾd Z3M+}+k/{]8&)P9@1q/͢>13|j"x_GFZ$⠐8߾%zLeFRu? QZձ('E%}ު@In83W `n [4Ek#Tr07hHE<Z.Trb^U[bc71bhwO^raVUR@Vak<>BY..ŘjNn*pcXT5#foUa0%Jd+iZPkeŸh`xǻL6~L(_#Ơp;f%<`2e6ȸs4UN`y,+I#ˆ*pr>`+ߐ!u ?gxqa.)Krs)q}W^ {g%ֱHEpRm3Gk/A][ldnMeA @ @NWM0A$Dd:2WZ8Zt5Cq]It Q$Jr zuK{@҃Iu5vymȶTeVfYrJ1c V GЎ$%G5nf򵟏eMu߿?J:Uw^dD6O/KXjpxV$M|L(:pHKԮ)2VиϜVj4bفSbo;gسQ'r>akMD:5FˈGCCA,>|Y1GwGZrօ/'Azk<^`c~||~|}ZP< $Pi*Ԭ~ = UA,Zޒk] !%d FU:ךXS3%R*Lc+"!͢OE?ƫE YqYk\5e\R$-Rmh+S-(}`)u879i$sO=0KJ5A+ uH3𤆡|zy!Hã j] h##i *g-n` /R\cpGZ-qMah- M$2hsկa=$r |B աTdUEcf<ĂFbru#Vc0[-HA njhb]|<-$'X vZ qUZ^\nC*RYK8%X%,b+fAẝ\ҒEB >m-2ݑwuQ[=y|kE DDkũӇآ:1{Gm db<DECL1+"ЗEvmanClQ(j?'s`] &sk%!CP%Ln`ؿ+fد"󡃿VIC|DT(h(ڲ\KY4O1m.I҆iyz;ugl9Ҵo͵f T%UJ1vQ;2CEgBTIxyIV7AӥT7; n%X%&2YbLXjs.(n?hP4y<}"]jEbrՠg+ܤ jX+p ۃ}ΓQi*kA@$1f ULfB'u}peU[׺*Y.Vk.pcoVsV7[l" (y.BM&@% sr{pרa I6H_j+\[`섙Di"R+bMbeQ=qI2M90A/am RxՃxp)t@F⠊g2x9w#=C;Y­ćeJ} A]lk ?dD4`rfj#EvW YWKm{p5epOuDS`Aimk+V5Ŝ|kV}S5*Ozrhf NGnInU5dRKt՝Ye KĐI"ǒ2$BktAlU"PXCNѓ,dDO\=3c }?`KĖ=~}s)[S΋WqXlW%%$PcnG YCu^vc /h'ƺNTJJȰWlw88V|Cc$mp+VƬ0lƢj=T[MV[FUbRuHHp]֕2t&2;6] m2M~5dȵXt* ۟JIg82uX (0.YI Ԥ_]"CyPB:"M]=$G42J.5sQ#gEȠ8ylN*"DkBeŁBWvvIʜ T/D䫏4ϝ݆(v pd@H0OVx/ D"$BY@ZхPJnN^ z#tꮖtHS[hL1\ %h}dMi%/ 28u]v޸ZWyUg`KȢg^D5ތowWmHz4f9-I\ vx9{uX4{ ȌxY6`HY=T"""Q! 7㣕)!pi&M 4o;ۣnZzkD֙T#5E~)“{2ؤ 9`J,C֪0ww"x*y)@Q+ Vpڦ-W6<#J@0.2vcpjDY!~UHTȊjH7H"<*̶MQ i")$O3/azpX uEOU'ق8[͑76lr }SyoI@ݖNDZ]xI}>6|{(@ʯd .,tm_cG Sxߠ_YwM+1+W`Lq͠k^I++iP7<# &1Z;S^Pban*C%c3WI葡ŇR)!J&^pT@O#( _Ze{ P%AMq"N9j9K*cJo`1 b\^zQ>b;|E5=qA I}Em!m!䫢-jqZ~9ygL3;+"z; iU_JzM,J(j++]ښ3FIݥ=~胬^ӕ[wB :}CYǀco+2ݧI/Tfa0V_2ѺV1P1Cd\k,a NYRp (գ m 󗞆8P.f[o2? `T**a2abZ29BڲSz[t.0ky]h׊UaE3JcxY|>"sjϷ  ͩO&z^`(KOya8ըZv,p_$ǀIENDB`gift-0.2.0/testdata/dst_median.png000066400000000000000000000733621513354670200171110ustar00rootroot00000000000000PNG  IHDRxԅOvIDATxlImYrn|/* e $#<3xbPEH$Md&EVUV6{5FZR{9{/h'`o1A1 ?6Вx `<1|F3'Y LAy5X5u9S+B@yh|ͯڛމ?Vb& 8q˵ZkTc=yIBGU}F#ƽq+o^\|gװ{p#o'r x4gǾ8GKʱ|Xjoo7/{[ӯ~˥}i,3dH}$dDۦw;`d%f.p!or ",c'?Ǝ'xcߘI?$,% *+e# j wX7J  ʟ-+`))#hm& ~\׭E1$ -e0$ZX\M T"MrYL9x!/yy+l7گ$ch96a{s8tAk,Y>;Ў_A;0gX猈?x蓿ʷ-wX!OBR=.]6̗\͞dX$} re4SM\!#w>i7=3=kxJb!bz7Y AuOd;AFX DwK?0Xuu5F9}7xYl FՉU;Zbއѿ.>w߃~y|#5&ӱʇY sZMx#oFD`n.s샑ynt~We@쓏Y3{4!!sPoZV],4FX, 9 %u`GN~7\)?H(·uäb V(\cuq>r8:ErRѽt~<ۛ /; )eș휪+kEoZƒWCQ{V[`fk +֏*?p}|l$<0ti8H狕?@{o7`XF?Zk2e/+]1iS6I0W\RZlľֱ;8]<wG˅l9ܿG΢lGYS9e,6Y؆i*ٶȶx k[ 0(ː ?Dhk&Ā)--D4ޠ3 )Q*P^P  >o3'f/·A\퀊wFX|~0kpv4z_6KZۍX'@T]yy lUQ,E&;2 >GE/8YVRabTSs֞G{B\X|K@7O^xQEZX:e9x,ADP=Ikm-4 "6aec2aȡ#1&a"ȢM b0r0oC\2E:źJHV%[g ,pb1s9|rQVG4}6=<{HdqGtM08+ |く=o}GAa"CVvə dg8+;[MHbʙR#i&GGy&͵c{o 1r)˫w~~z FZnr Էo7h-ܽkU!آnY6;9]S.;F|^ ;TVw``EVBws[C*QXu"j[_l}:_ǥ17׊xc"R.Mqe|x}w?{zcX Maa ea [dhd!ݬi]s=b2b9͎@ج@xԭ:ԓxlw+ >~gи5f`-[ +h$-@U짏?ʃ^1N_.2+UpGńb~qm@֕w0!2 %51KK&C/{A=@آg$ӒEST ( O9D On6{~dǀ{Vy]UNf-N6pNيeYNv45f]ݡ*k&'wr>?}"cz5 E?èEJppAbEjTܝA"[, Z+`o͎$*7k'w.nn*jNnRd !f'V<)dBO=01^9.w?AoDi:sG8v V.IGnYֈ3r21riNl?#9Ӧϩpܫ;ꅎʲ5;#+H ֜9F''0 MFM׈|Gf(/>ә=M8EIDGV#!+wP5"E ak(( 8XS Hr?A<ԯ,'ΎFp\²Su*8Ŋv pϱ &* #!4GQdfu_=W4h;5-,KMJYE)ҪBջJaiR*#W{w&bd2XX$k*ڇ[e[ov"2 vPAt4TrBڦMG__ @;@`G"L hSP E<|5É'5[YhX<ƹbs*Y;c,tk1LۓӓiۜE}t䋗/IvĤ[IO5rVZFzl9<+.n#̹fBJUI@={b&%ߝN0Zs2'ӓ&P'492F`g CPkwdRuvLחWIPir923EjU-+%Aj JEZ7VGj@s\00&.x+nrЎwz:=4#1g/_,+L)>R,ZeV]@!**; ,96 r 9j eȖ\CpHM؉5vvF6sR '$d9wV"P:[%V"5[Th!0Y@{sƘ@*%`1jTxV] K 76΋wb!prM6K͜uGwBX,n@3 _;'GkfBj'P✭Hl QC-YhhL"pLRε4']kŴ)srBĞboGFY ܍RV(Otj%Snϊoʟm|k]#Rɛ8 ]$M+;68ϼ~x"孪Yk L *({[RQxW͢fѴg ]%2S9erld k8M`Wd.@nC'f~:*͌h5%+Q&(ᖲZ MEq"[{v|p:pFxB9&T4΀ ~:ikUv/6#Qm.,)Še g6Bj|Vk*|lXOLM-x-ŷnA}D!b5rETiFu6TsMӴ8klqYEئj"(S̊r4Cywt|؁ >ʹE j|+'2gOqe5׬HF";HXe3eAt&]"ۃ;GCaM#qz_Ҟ-%o: xєLrm:ZumYKz4*8LJ*]m2G ?jamFAiGӓ U$̬U_v.4 o aZYjIk|[,iߴ6LڢUd5*YPK8;v9Rt2y3Je @B^8~,.^< $1xsTp%?h<%(.N2VKl7ѝ{oٮbze(S9(~8?Z2J6BΌC֢soZY2hƾYvXhlAKW][hfXBXcTb 3U0ۭumqA.TEVvmZ j=ƻF? 5IyL@z˚I$ACPK&SasBL q3$y~>Y@ KTkO9b`TREO=nɜA1g)@`.NN0ن!!+֋J5h2m7Ew6 x39e[W;`H EmJ 7n/z K 96rWJ]m_%'($1׈QϩdeocUHhZɂtNqk-a ez9܍\shZ_ }z8u#/7u P$Urcŀl?6C^.UXd}cEve UB+JLקPɶRLbq L&)f 9*@j4B+ .؊kT2 h`r60X`7Pk{]!5S2ZQ4a}kg1aT0S^ioF=(BK!nLki\W>ZNuhZk!% ::o+Tq0a)`h 6 "$-@ +(.E7`&UPM=ۄueFE^|Zdjڦi[rV!`xE_&icn!^ qf0QAU FMw :-Ⱥzgđ \xmw[G˴&`J X "תQ JYȷ Ishvȴܔ25]7,]/xjȲS-X2 ќ|T2sP Ru[&hvՒT+kd )CNPtTibHӨ4vZg^y~s33~}xꋗU𫹹k$kT8Yϟ|ch3}以\[y&b[UՋ:΋C0,WBSU4i 2T^Nv}7(ic7WU\!o%Ŏ#īzd Ě|lHRoy+kCMSb^lg^?,5N͙(7~~2.qH)uLq }|z-'"ĸO`[()6J %"%n$n6M;j|,z#1/\ܼF^TY]kvA̮gkd,X9/.Tm?s{rma)A.wv\], +P%'gkc<5[gL{xp0lS.☌n8239^ V0)K9PHB(r1AI@2i&޵179CM9pBjR,2˷@6qZrXR4m!2ޮVd$j[*p愴x(׺p1yۊ ,j5EŊ Z2(a niZA`51,9W3+Pp:5Dpkt 9?#0 Bt V@gӹi"Xo1 dƓlͶ2lkr)eĜ})<\_/;mӐ{CA2Eq!uLUPʠb]:K !R)k[Ks/Th/p%9oYۗ/fpwヮۦ)mf1|(@*-AV?` `_jD_@8nRt^^S שEWQ 4aAp.;[ ^{5NC~7.ڬWXio?/eqrk QJ-$hLEgj`Bm61Z;zml7\)\l%v I#*\d0fdo}\[N voX( [\.Ģx#ʀg(, &ü_?[ ׊r6ݕ v.<>hvﶕ 'jͷ\SCA> x}7د}E^@0duPzQPK+847n*m9([80 {~v_6Y0f"L|͟şe,T /Tʅ%v)iρ0`ӓ'O>r06^Bh(hŔ5cs8C gGDV2dзM6yS$w^W[k{$/Q^$-ulkl3q)7X$rv Ƽc 1`5rOPIt+ >b=THb~l + Ut5!#WGzts&bO5'2T m!ɟXbLR*Hx/?󛛿~]}TF USKkJM4r(8,sr[TU]8[dͮn -QYE]p,> S.ȥP) {ƠRah_dhZ/HANثZ* b />۽hrc^3d]2h_a\f#wJ&^on<_d$+I&uQJ~eWx|#w]wMcs=smɉ_s)͖dʔ8|)>SK˹ 6X?r'dZY1SIy0L- *j~+@Fj:¢y 5q/ycHv땆{GO1ٌL<^orJ9\l~.~@)SZ8,UNg[Ʒ7Ͷ02-6+A̳61%ڙiX7ļs2_qPF(|5/dwg{ 0VwyM|04-zoV.U"ʰUVub-opzA)(u*TInj$7rIli!g22cBv1\軔oWSæ_.ooc賺J9>Sʫ^mVWv%xrzzvt|0U 2Rf؎|ҚWZ3jƍomS'O89!*9WT-p!vYͰ}Sjq;)t DJ-;Zs\D62TlEтВo.O1w_ՈCm~maM꯵$Tș}$*!܃I<:p%B䁳R T rL>}gڶ0hͬv\NfԞT4Q𣿟JhR9t8ᝯ>߁Ј]GV/u96 Dj)(V3ICPPsuN y ̃,]3"% r)*[spdTВX-=cJ@G][=\$ 6m7RB A`C#˛x{ ёcTUĒ׫#5PĘ ˗1omvv Aʍf}#˩U\{ҏ\sͭmPŹ]e޶zH3$5CEwzri; %#Ut029K´&yEPǢ\L4\ )TqC:OfYU` U$lvU UlB"RWxVG ᠗|ţ;YsKaSwX0Fʚk&SL;Q69Mܬ }_R=[ }^l}j G zMM؜wleY@޶ڥ) )30d+J1o0B^&FSy*@(GjNOy3QP\= &Vjfdu)!iOe|2HN@y9ndic}v%"^h+ o>sлv.-4iM]sR!o0#7 Ė.a5oxLְE)J3:0ĽB%0U Bb$"4kAXTޢk&q8XaD:h~u "zgq%"NrPScJ&$5x֎FOoDM{D܇|h`iCÆZ_zhP@0ti-/V@VDY|΍lGA"A6c>]rmrx5'o.!+^1n8QeT*7%ILՠD7Һm{4Ӂ|;`m`\M:% :$2`r3#7zj0iabPAɽC/wr;ki0 B! 쌗\N`~ v6ISuK41&< x{1V%phYhb\c>t ˸n#PKH<QlE,Ԯ=6Ђk6^sо~s̓+Y>Z& `Vi/0'Eߖc;ÑJYXŴCmHӞ lJ l+ J`č9I|p`L[=!aIl@yҢ<<@|?g~6!'N.Ի4#gPMVECwZ(}ơ}nWX>>Mfw`д2g)rILmHZPmNط}\?=36g?3K Asv:,a!_V$2YWt*mNra nK+l\.x߷C2}V/UɆKWp9f08+^ 䀲Q%D u@47~׾ q3]s~ꟾFo:kuS?3Iz9sV7MSPĝy' Ri֏ Rm=Q ;kl+ 1Q~jk{lFlί9u_'$p}1uxDa\b7?=! DD)4T9A*m0p/obiƔzl.uKލkCU5Se^B6h h{t|^޲٘Bև-Uȉ=ǵ3N\K)\<}my}s%x  ΢X`?/gWNT!~Wn΂@PmDEï* [ $έqgނ9`b24}cl6w߀=<.w}^v?[WU>~';(f88RI[%T_e\,UEŒN,';䒘в5e E/WE~}x@@ ks[h)I@a0b%Oۿ'L<( ٬<}/nWm.y(T)e 0oDc=@۴?<VLi/qbZi-C:;vlSN 7)D&IR='EmOLuɬ.vߧS yS>)_N!)2J*Q8(Ok*#F,~=@$-ȱq- ;.A!/ȑRLQU,eG0\)yh4e@o;Z"1"st~qQDJ1#)% B |q9D>~#4j޶ՂJ@*Hƻw?dˋeꡌQ[Њ!X&Z:{e!VC[5Y5 v&e[ Z3DY}ӛ0/s&^BcTz(ꅂI i[)WMQnJCw1˓f𘊙:?X99/1P&JP7i#&<_u t I: ϐ"JN)Gy5^/1f\| !?tAa a*Mj܇]{ ͳ?].rIq%G鴡[)o*ԓ y 06.wc2a'Eڶq eziA-6@?Zo0UH9$Ƙ,B#9)AI9xadŰBM6RP'S\Uo$JXZFiV}\IkYj  Ip~i|#_r9u8"v鐾Iw? .|Q䵞=NJ:crY[KAU%*l ik 'Փ@kZen MyBZFDTk"jC">*Ԣ( [.i|~*R@vVSx wAޱ$3B tfs)=j9 2또a$_%%!3j[uҳ+񂰢Dr.'}cw}Y%àCJ1Ie;s04h.u`6Z.yR}q4?XYR '[*SԨY2rJ"uLi@$=ra^ȩ}cbIo@\Cϴ n̫L"m F@pחUUbAtߤW 8+^ \oBpX/M3ё3ܛ˟; N;r8rȘ(DQ`0%'e8s/`IջIcuePDZ[|hQZ34(;Fyo!6Ha1>!ԧ@mm) jy)^ {mHQ'׸ԋ ぬnBa5l! Aqs:|AthSU7& `9;'SLe/Zpn\Wa[fݟ|Cw`'QT+٢F7)NZ{cO^FDvC7uc(skdS&5j3]^؊OAL.BІTh:L6%.Jw6648vY_n!^N77yS&>JSTZ*P-\jq[IȜSm Z^lj3bJ vIMB"D9J5RFӒ23 mCKp+^և֑r`O Y~}7~(Y~|tqWCNTT`r^-RуA|΃,pฝz|燓/X9P-C([ϣ }8/fy8CkM*co+lZ# EVGگ>Pv褉uҕSY= <BNK][/S)k^x {ݱ`:o1.>_je͉^5@dX<}YİxV$J[YZw;(n\N6IT6=Ҹ<0/%F'p@kh7^ ȑ HupSK[V]w^C@X:o6'9+IgYZ0 6Nj*VUK#ҼEqQ3I:֣qgaIy\XZjgq%P,# ys:(ҍa1^Xw}:hdKp#[?ث$\SLv9C bٷtWSVH0*LMRJwЖ9/)!:D"pjѵUX{!N߫}1io{xK۰\Ĺ0]>e:ώs}Nނ m\wF9 |CĊF\hy^We om1Yf6m`U t[a FpC+2dfjJ$ޒ~0ס!:HGA~6>R/Z / ("=6Ls_&K_r/qoJ3U@ࡑ7 &-;0)3gH{{a.r ~S7,5E6JӄkI lzNg`_@+@GpOG pQC;'>^%R$}! 32-# A_KO_|ոՃ%93] ȄZU㬱m>B`_3#>aq`-p`ͰNiYvXC4\':AP!c-i_~*Ae}{P S؂3fG%TDTN!CD\ߴGd(,2=@g_nf~#mM:h'I]+8QALc&Cަmf*-f7ԯxJViO)C7}ذܧ2\fEGaZ_}xt\-]"ad̶!:۶AiArZ/D l5y|'B :ma}k>G)c(QA[,l sBy{K_5iֽlwfMͷ] B(u,Ǵo]rOdW\җISi-)r E[" 47 ٬/~|g9<~Ll ޝ8mB2&;==3S 7T>|D9tO#g&K{. =t"YFU, N{ 'p~CD\)5%R`WJ` ʊ}ܠ&,6VNWhf5\RLZ5VAopor1H>6nfs6_nv1/eN@1p1L'Dd$qN)p& ijmo  HuX 4zoZ4Lh n'O5  b Pqv34g6|;}Wag"]xHvi\f{Cڗ9<'T|]W"m鿗 !!90EYgj֪ncF&18fE[ _B_0 ?}pW~>L>+ׯ-.Y, T x&@!$`R8Hz qʠtKI7SY"%Xp}xUݿZCv~EEkYRҠlQ^)S^c$|.e]|v4KMZ} zPNU< gT&#ȟލ^S)m] ǖ3jm4nB M**F#(1%xI5P $ši{9<}]\s\tj 27 "Y85`k!l\QDdp{2r|qh(1k-9 _2m[*aKʻ&\'oIqﯿyG|Rބ(~z7ƉUK\rs'[Dt_3qDgm;ن .9D+J|@OW\AiTv(W6}JLk<3%Ҷ%8]8 ӛX(RDYEc)3?%B4z>^=LM<*K@l)~τChv)ȷ$-J.1 b].]ˮu68DnG})c=ni"ÛAݤ˫Z}R<{S˜n/_ cf*Qsom& mZ ZN==.3x"e^ӥq/sZkXiaF?0w^?7rNڞ\xC _ܣ*TE2_*ɝu8f#FBٶu6݌v8ob[g (]LKEwʎ=?(}؉t{zB?h itjBm]ώoW%ۆZ g7DyƊOO f&Z 4mFREz)VZʚZk@R:w`?騝ߐ0 ԴL[G#NWJӝE|u]̅]i"\5q]1EK {r5a!, dZ Mq7쇵I:ܤ4WsQQ^û%;Eo8ot9 bJ nuimsmv"̈7a[9sĘR^^.}qYy9.D r!0Ġ_'RM_Y}B9 8R;W~o/:Z7oWN.Ss(h&rƵn_5 Nm*ÞVG6N#N$(K,5Y~%WO8BLO(.[G{BD=~S/`\Z>L[&߈LO?qYNq7rEl@z=4)H> r~%gzr^_^.><~ͧo?_^N2hhcq8Na:4DOfK.Cx&z>ܼ??$̌柾]?J~VRJ$bep5zL\Eglyn@ue )%b)&[s+Ɗi9\ TBLÒ]yM6|ٳ{/C8Lg\>Ng7CwpES8~F|[v׿/FoNC5es:ƆNJe+*'].mHi xzXy.<9s'."~HPk_ikhY9ڵ\38(`WM]Ï6DR՜AC)щٚENkx|<_Kth+MDe־8woh,yUi tV8(Oe%<J)a%I8S So1|]b2D*k 43&鹏J8r!OoF#́d 4:sowݼm6NX"!Dn6j@0=j:ƶp[kȚF[֘A$dڧuX~zm ^Xqa45#ѰrZ@nϏ)e5bsnS$fzx}/͛~KY/^f;8|kKpԶJ,k5HIS, HLiz@FGpYI"JQD` #4j I:jUO79@PJ/1~J; N~Y=ֿ%,C7DžوoM.ziaGNJɒ6RX?ai]S=2נ]ȪH \<Ro.1?2޾R_$u]<_xHwn^_09̀ C29=ּk} "k̾!Od]Ijr G.鍆"#G.l'zWNR~;ԈŠRpAGi+Doi>xCh Vmb;"hE|z|}noRt7ܟԻ_7/ imZj $Fb&>Pی4IkHŇ,pǻ/8ފ5;؋d raq-PsqBH|1a<>\(wmTR"iU{Qlh?@(b,IRn[~?Ot p-A6mƵJozty;ZGuEǑP`т U G'ϳSW=G,h)mAYж5+Sa 8a#iA@_?ܿzësZ)} -k 5ћ7Dt;ݢ+(9.k.L>5ɟOt͗CMw7j$XY3 h̻J4,cO8MK2T+_&-M05V4x/deC+BkoiX[VI7tLn+Ka%)W:H=LwLN7Qu"& \x;{QvPNsa@' ('-9x?ެk!<Ǘrz>.+؁':sSL_}xwշ}eִbm\ FY\ǀ7jc'Vhz g[S6\_5ls|_EqʼnNqLdk\uQU9)Ym̟e9Qv%ڢ~:1|jAcwQxg&Vō'#YRqYԨT_Zy4r:_N˹ukH3fÑ x~9Ý>.i}.%Sk/dvRw *I$z>yو>Q[ bj l>Tvbu}6V َs:EF.ҔG&_9xbvNJ5hHI1m^gN8Cd,%6Unɻe]JJ.,)e=N.5EXhkM<.yy>.7 By]s9'53wGv- 3N7Tߤpo+qS7\ib7`=*,F^[hCɜ_s=8-d8 0B}tUV14LLTu/̿ rVȮNa=zFHb&CpOGH s9,g)t벤K˺}Wʲ5x7*%q-B-9%-G{i>SpBT܍tsrO뺬k}-ovdEaü̩qݼBk&$Mjp޷w]p*)ژR 5/Sh%+\_iQ2ʁZQ8W0%Cl{\f7QZ6/ 2u߾kHBC'?B ?Az_mi `,&Th(8 ~@}cm5s|̧TJLq9ciAe4`2榽HӚ,qQ^(E%4g$`No+ dV=%Znʐz:Y[jdT=^.?yrC}~չU*\ͩTbWi*[R.jS,VQ‰ΐEq6%l[te`h3}|}1Hސ@/i,ʉ\՝u옿Aju>hVw2DY? jmIv, 6A"id΍aEU%KW w;(TT)EN Bc=WVFwdJ1te7ҘЎMW;znw0_:LSLbN'=a0:8)\5j8ewkK1ߺ] yNe+ S\O˛@7G* 9?4o^=P9ejUp3|*"@!;Gr좮%c'nǔ%+f4Xf.5HKDڸӻU՚,@3-ĩVLdu4Դ9`y# ahL'7 GJH l8WrrIZ;S-GȦD|]Y4`I!8gi]#,8&Ц_stn--(eW:7^?4 ~,GcjoᔖqM4Z跅w=Y5(B4Z_.3iWT:'q`^r~w:Н]ujݳ\ѫ7_Am7XUPB Bl+Edp!ܡƾ[}EE_v )-:Q[7²ei>?^׈O$SyW4oDkK'Kcdӄ߳ pq5CFDknVeM֛[R 94Lt٠@! [c[Au8en<,k:#kZ,yI/)*Pi-֗M8!s:|jpe)IrK|>]mE?1ح:s474fdC{Z$SOڱP`^NY&1M~PO9oƎ?#VE a#9gBi,&G˽,(8e_+@ZX`gcrj LsJe)e=}Ya[2Ql"@6`Z'%9*1?2cI<x|L7PD"d\΂ŰNQ[?ta[CZZ25|f=aa SF;lg 1u62ȕL3u؄v1e')&v!Ŵw&w5AEaÎ;ł0:iҟ?9C,jZXK;sP&~)h\hHˠC@JP (`C f0ڵ56 jk,huI^lEP"@V8Z஥n+%$rlΔrWي i^6B%ҾQsHH?wgW?N7K%+QP/O2TVd6,PHnttk]8{؇>YF0Y j;VG %+v`sTSQm> ӏxUXFNLWck8=Qm&9ahS:7N:T{Plm2M?2AAMTė|F)`H*#T.Ύ\8/]-M)*Q = \E=H"h( q|upmiyT!k\[>YA1OQtelU82uYEHvH,Z5M  `DT5VDİ16L5 R8tM‫P=I",9F+_ripj ʲGciSZML #eZkINRLgjLԜԧxu*b>325HO}U y4ֽVp^m`E%h;85U2TǞLsLQuV^Uu^(8I ^ayHjLI5Y9TkP*;Hz0[g(dqYio*6TH{4պ @["Sˠ6k:H4krAA}XfY]m;ܐFQXr|M3B@~4FNcvODJ'R+blZAӺxqI뚰3Wi R d>sq8v9`@x W q*KAppDĚS%uIe]XROuFxٺ5$)eZdk$ЌC+|!cG}xV hg*EbuM6Jt[k( }̼ׯn|x<*jC.x? >cMtէFj7#ΝDPRmRy7ub=wGJ@I6vjfjfKl?NԸ JG,와u5I@ {,*KKeKNÐ1f~`*RC XF.a"MGt}ۖ1Qlc\bLK\R3Ud  Eg+Ҹy'dvÑy1JPMbi.6ӛJ4CiT)LMmɷt!_ij$S^l⬜qَw84gt@\YERPb5CR4&\D@<\Qb%~e'TܲWI9֔Wjtd]V[-U:l>lm] nԶ?s۰Fڱރ,AQaT2D'Ud |A{d5Dfe5zaH.;;Yh"i~!kreɅBɶ]ԡ,.TS2ЀRNI->ۡSLRu*nsZrYkz\0y=<( s#p H~sཋcpC=ˁOC ImbcwA oށ_,m~E`&B+cf(T oM1v);MKY?O7r^o1^ϯ> lӜ(_ \Cr[!B~fzf@dk?pORJyF(pIc8.:O[t^#cĄ,;E;f(-AD$f@$d@€$+̙);()l[pϛ>1] #z=A>MIq^?: 7:XMI@Mx CB ~7@18y\;ȐMʝfrqi6I%rYj.{&>"vW/aMow}! "犃಑</>zpB + =q}[5>tr2.ɻQ%=Nxti[ lwg#Ew{8]Cr=C?]|7yW4ezY竹(cS ,eV֓DʢSb<q<$6N/b'ddfy f89g38r1Cd{d|1&Ëj:EMͺu{MW|x1ȶ^O:}/>*.:r! R#%vtd .Ȭt~ȉdA( =`] !*uDsؑcLv 1"\eO# {q/ttz{#dR'10sޥ DcUpض]JC^:Nlc-9t{ H3xGY|w9c3qP?l߼n:\%.FY65r !*FlS^>y ,; 쓷cC' H_a&GΙ%Q`W2u:ӀŽ1beY 2=y;+!p%A@#kK ɲ0Ői[݆i]P|Ň,b=@Hl;fD.1Y̚"PrΆU5ij9b HKK fʛVхhYLmHm4 a{>!CJM6҇6o>Ō .4ƶYf+F, )y9!* U/ѫl([jé]S z~ֳj' T%/b ()?ϷCKLCb-2vDf dAC 7ydsxx]7;Y//חЄ2f+HMwcqVMWFtQ6㧛^I/ ) >H'gfQ.hCL7)mf6oD 5ԟw;Y=|GƸ l 4k9Ez{W.f1Gn Ɨ#Rz,ȷv(@-t917XJA C]ڶIkbQU7C!#bNFb.5+iHNP0!bf[';-9-4QGdn0QHŶI11/Aτm1Uڶ W[q4#ǫr 8ka\5UJwbۨb6՝DLqPB>P!2blѬ|t*ᘬ(@&)İ1 5^y cj*Hc&ѫbTkHM \@1AmGrl9/!b $V߾8WrN֗{k^w4XFHI!L#FN/!%ss/ vqDIdsܗސT|grĘ}#co $|'ȱEY՜ȝ]Ud`$&/b̪FUR Gᤚ(DqBYnMvT__\HkU@MWRfjFx.X Fl3 2Y)M#'HblԳcŇpZ1G:LH׈5LI ^!"JP{hyr1V)20аYf F4G7B!nMf8z_Cא<W/F,"\>:&rF\(#%= oj6v-󳹙Z۩jd>ALLNHc*brT-۠Kp5IflCii# qQDxM׋Yir1Ir'מDUEJLXi9PryB1y7 y{6WΉ((H g>A $أw+2jE z %s ☷ $nu \\p;g1()xˋKGb@|-|`xEAγV/s%>pXTdCP>`5I%-T@/b|IY$H\?rRhDcB-Dh>D-ZB+Mb#ATw+>v*D [4痋ӶYuˌ۫_}ɗhf֕rMf$p\/0>AŀC MQu.p3ҦEr (Đ"#c"^Fe1_]_|xb~W) !ܤLwm}#3nn rءSPBBXc5. Ezxv2OȨ <8ʆcM^҈l 0ٴr,uBA`8ٜK-!pq?Hln~7M6k85Fk/@& S]RBiFaA"$ŇcqC!YjS؟zđh#F4.B?:t#v/fZc&|p[4Б]]|GǶm55ũJzS$LyNT{\n_N: $6Qݬxq-yM&4r(}PJY2S"LbISR$OJV&bZ^mCo *J0"%ސx̝^Gi~ wׇHq @7ӛ-};dh1W byC2d|3N\fBd0pdLQBNNmlfbauuM{@'N !D4dteKugr&(D8{w~eZ!ia XZlK<ٞ RhU  =7wU˨N) ,{ДclCjRiGWISAr-€ nbZ.٥Փ;ᮔa8rd|'☟{P.5$b"d%v;;'4Ӌ{.:S(>fVVa ӜpY,㢁${eS$.+xqr<9mMnnR6b%wO>;߶KZǓI1h-2N0 Mًg3v!m(RP,?2-dIۣT@X}F-rT,S k[}]lol38TZX @G{X;dFPYAM aȤXX,1?xgyĜK)ea D~b@Z8_EĄ@#Saxvjz$ C;1Qk>-+Cc iht/>]evU.i3d Ū&4wq^If*&d"GgrGN 9LfYjQQn"6j#qbE!}Uª>Rke"r =j` vIx@nN[h}8`ʼTVRlL-J>>vs͘" 맢8P7L7)<{eҩ\hy7Go]/T㙳FIQNKҳ&ܣñ?3G8F D/ ~"3*'G(16e^5)Hݦ'n޺8 Wjk"YFB/(86X> ^8LedfM1 5.e,Av&*z. 1ze- Yn WpMܤМjPWR*fWAj׏>Oe?pUq!$%'UG(,{B9)TS"LEwZB"ȹg="9ΔKp ݨ$;EPnx !51Kb!ùBjV7{Xޟ+2rzc1_,DetsTgZ5{H!694.IljJPj1 JLz\,-J]д@<-^DMInU5 By@3+! MlCg 40SO8}YATfw0O泥_fAU |kd8YTKpz@ 렋o ]X<,ּ<3,8I 9όHxrLרּRw=ŽWmk0u ؋aM4i-T&JGiV?- !蠜|@(gTJ[tw0]S#8cadOu2RdgƯ?s+|ʦX ڈ⎥#m %xPWenp.C!튨Q.І,j:e4Q8!6ebX*2b#$By0]EdžE p,L^Pz cq߼qcҋĿ&ɩSAF~.diO^g9!]1jJ]U,iPb2W)DS }m^zu|=<8[F[d\cM.y,#QAZNqRRj]y7a&峥+ozhRs]USĚH<.xgL?HIg WyMBP?*RjT%TjQ[L<y-@s74q gJ>-@=efh#f3l=g͌aw"'UΫSA2LȚtwib"AƝKo9y`}Wt>5#!I־0Œ0519c4VEq%GgjDצ:xNIl~#&{v)HS!yizT4K )mpecMPWa0ÇFXﵸEUkQmZ5}?f=h(Oʂp)EPFG\'r_>?y%I Za3xHcJFRX,Ԗl#m~(]wO/.u (b0 17Qy؛B;ofn _⫈n6] GN]wjڇ&'bGdeL hV񐏋ŐiՇ$^QkcqcsOug6h[ i /Iyĕ0zp?{bsI?B fUj%q.~ пnExi~tW|R('&ِ!/h{Fc{櫯 Voi[`m jaj.*>E>=}ƫhɪ815cOMU'r֐MC0*wqT#aZ( c?Ӄ ЯuBCC IU.o4oVo1՘ _MRS9:ly fw/a9cИhHp(etg<7y66m$M9]>TؿJ2>D+\l/^Hiuzy/@zG)U#B^>n~A89lowKߤln\]_qUSSd(~98=Z_5Xs9s@Gy@;;S(Q\޺  ^`>ٶ?+ȃ>VOQA1xCj\mt0krfAm]_.Oo?M>wԝ2''viC=>^œ /22.3zR=\oʐQ([&4TlmS>{Jqm4dp.T3 rmq d1[>oXQ*2f:; 7[g לaYMۣ@ djŭkvk 쎚f0^[p] ?!VM4X+J)&ܑoL^*w~~2Ngl_ʐWB f0vÇѻ/_>k\Xh$Sml 8qCW6vmkU`biTWU8&YtIMhfVi Gu7^9g4&a4V ttlK[,ϚߓNav?`=S枽9B\tFB\h}MZe o:E@xhÇ7TFۚ1y;>侣XYbamd|l8D6 D}/ءՌ`:&?f4 0:A\]jdYMj"ԔT15YBJQrmцh)`h6,Xqcvc U4@퍪v*&+P2OvcZ^_ _Ja*&.aNfD LB|vڄ6#Z.px7G:Bj֏S8Oe#CF@pFd͊Z)lZ 3*Dԯ r~&|4/’MYF|LS5EY; 5k@SQeTTbcD].<$m71n2Lo8"+d*4䢥Aˀy a 0<3Mơć $e2$^F3D{ۘ+W ?hRsJ5[pp<#V!3ڎ`Ȉ |ⲛU(bY Yo w@U >&dXf?£{s@GLf[Ĵ847wiMTdQ>\@T&4-6**VD꤉u7l~&L"3Y"SA0-‹}CKFڈ#΅ Q5Jp 7B=R.GXd0ʱ.>6Oj d`p,5;^..//..OϖWmG!cvUs[82jsv:!LMCPCFVzaa*QL]8Kn6ƐťA`v2:j8աa[R}PS)c]Mxy!6`H3JxSuՋĩXiKN1lbr~X4rc% tXB=X:bZw*h9.ӗZAJE3ywfӓ{g~?|(ifֱ[6ݼ/ټ戌Eu5aēi=5 Սw'L 4UzI4j65d2L7t2=h $:R`QK[ɲ#|V~t7BzKɸ)dtp{&hy>?7fAF\d(!3c!:18_\:G9Qի֒BǪcc=@|خRC>Ʀm%ҭt}n[)2\ n_n!zoh/ːSьE}گTd D:* qG[W~ 79T)f (# !plu2!6E JGQ5a!pEV4D$(]>E[ʁ"P(#p5W/ya^m6r=[vaV"9x5!@p!E244ͪ[!ay" wra?I-U_\_qon0mq\.e!FXm 4rv!&1k_faVQj7眒4/T"S:Y*eRnp?O_pݬ&''=(uj;+i0iA,21A&?jetRKejbc#VRQizѱ)El9޽4nT\34]qo,ttO'' s6d\r9_<v ӑˆ|6`m> l娉 q-nW!}QSg-ژ5ש@Aj-El[Lo)P*Dg-ZqMc,κ =7nM˱3|sO÷ĐԸ&hN>ap(fޫu2!E^Li:b}Ֆ75?U  *l m@RhKޣ` [{>䒯 sCF/4cɥdE`pusGZtz0RHa4SHg_|*2 2 ?Ȯ ܚ MREM ^OlVckMiY!3IAҴ =ѕr+xSbFBkg!>" |{]e\ֳL5g]vMM8Vj JnZ4xM2N f2$ɇޣ a2dXPͣ__o&~Lew/ūA_B ex0&o=SQ*8ঙ[ci-)*\8ژFzJJp[W5gcq}G>mQ!=|K&<>`aƿ4o>ſȂ%C .kBJ >IP:(եczن?isA@9GnS3(/'?>Ǿ}@A1;źf0ۗ?"o.(bv믟jݫXWŕGovbӤb韏%PBM QgH!?ea[4Y@֡a# d5W #mG0K_!1/fAdk?OUNڼ>~K5OV$G9ԁcy(%,/.ƣ)3VK!/1 "QQ" e$ػY)~zs5`9~ #sݱߏc.c?͌qw)/F݄=q ,*\jG4먱nwۿOߺG,M3s bm_]v۱X4SoټD I1w|VbY\SY88RfR mmK@]pZ*tn5a=3Y//s%\ũsm~?0G[Qaѯ}=#̾uwAxX0 pXw&>L-iXOø; ar-_ !4iF(>K[X|-\4ޥm~|(sN+qy#X2f9#,p,捪k:#24<&q4 j!8C<+uD&*#>cy/ma}F^'`~ωѡ\])+S6-܍vO?49jˠ{mh 'ehCKv15js>@B-i>1CBb*M8KxF$$t%3U|X8 /:HIsj>o1p݇87l"r5Y (4 #9:숂QcS0Sʨ%1`1Wj\j*R1Zx/1HʷPvp;pC/yiZUCuxmyu> biʢʔȰG__Ýܽ< W6{RS]?3)jj./铫R1W'ycXL2E;%ZI[?d T9a_04nJHݾN}?n0h=3Qr!\ˀ Ea-YAL?: &I,ƺ*>eDb@=P8rBg}*g+rq恙l7e5'=#w,;m7^^s}| Fi,w?7~"dZ0M>]#Uw6y? s~ŷ_J#^($ƞo; >`{H$1Jyg781%c ؑ6RŁ0e5wl-}B4 cN' '6:> \+!Ӱ]8=F\"a, j8ܬ8 0Dc8F<=7kU ] >xW`6o csDA'FAu{k}g!~| {JH5㘇ph\h"&.aZ4Nue}j}廐)=s:/Nt7RA,s!KgF*|FL.)ЊV2&e#+/ *Y#!⬵йR>@/ٙbTw\jKx@1y{]E1<<_*2ow4$dg|~{IUo\tP V0w2n~hf8Wf q~.e,dBYkTt93 = PiP6\`D1Byq EOݰPh*}52,K*`l=$!0I ^e1C]TjʹN4 A<>\ 2dp//lLf))|w<w~1<?V/zqN7,fOm^ȧP3 >~?# fZۜqʐbxiKSrp ݲY?fp%Bh;x 6 ln؎%9)OǧN%~TLm,xJ5Vv~)7(E&~ro6LJu-OM=5}F泛%G.,~g;GϜparz^M:`G#R{5sc7T(R~huUd"{n8ˋ{Ȁ6f$*:dVeRȇR*erDF] {sws֧q  6rH 1xU vJ@}Y#>Hi c052jo8yT@\~9kQ)5]o_= ΩS&W2TiDx, b_R i_y`xR8:~F0G#Ry6B,G`w%6H냄mAEwou> #4 p #,e& P\(xrb w~1$  Gxſqw]>eHL|4!mR6dpEъ}p4$;nMakuEbM'RrU(oABjJ;h2i*RBR%owg SǼvm.yT||\s*ZA*f1N8jt08ש*ւ-:=xola>%F.lUY 'bIPCȵ6a74p ߄ܓ͕{,Կ K;cɊ>;W)6%1|m'$ξB]]Q9ob nB0WkS!qzLf0  j:!"c999>hOl||~ŮE' ܏d8Lj8:燍ʡw+!&1n/Z~yޔfO%00 {ş'_6 _p3#x:Ȑ|h=[fk?->v@}풗<?v %#>B)417.ALOOЦk6qA]0SM Iݣ>j[_$H>[}Uč @r[[);B շFl1=='g:iSqjME≉c.\k7,Wh~URJq-'ɗ@ 8p!w#{ϯ {n>9z,K313ssȥz!Mfg^ Oգ @ |P\d=DTF]qss[r<,G;6񑶧_m?|`G ف/ޮ'u=o爌Y$() @i$]%1I{naq9~~1S./T0t5G:,)CA"H`B+њ?I:j ɍ}]q.*FwƱ9LG|ȘCў@IQ?_E8àt-@(͙Xfk>(t{1["n_~Nߞ;q<>5sá=m4ckȩɗ/Wۿ(Ưo?j}ֵ͚[U\+ME \SFknIi.AI\zM7Y?}{nO_ܛr*R-ۇ[zwj: "gx}bn$9e!NB)S*E%sO]#7T뻲F2)xP}FF@Dz>ӶnFmY?Yd~Kwz|ѬhFLt"I96zޡ Z.K'ʒl * Ԥɑ0ZBKQw7ǑR;avMy?__[ύHXՁA7Oz?ӛ#OؤuMsgbZʑcetrea3K̍D,Y,MаNFǸI9@Y3`K#z"*F#C/=UÉՌr1/,@ޤFۧ]Ճ'eTчDFj ic׆#P*\#vS9}R:vPwẈV=\i(-P>nSÿfF.tC;\T:z8.BtIo*co$)`84Vx А^b ќ,.P\[bg>ohxq2Iv0" H&ut%$3}l7T"c9~3=!@w /䶣s, }IRX2wxicGm6jVoZS$q)x7^fhV2/~m'ҵ]ڕZMu;L۫qD厺LJɎZ̅XSWq;}E 쁖; :NB=۳$cO'A~1IeUq'uB[t rQ5oFu\G 5 |D.>𿿌֩WƯOB^oz:"ylo+f\h".Թpi#)Z/mbBMMc([FVX?4\&>թ7ߣmZZwȕTQ,롹̟†ᒠlv2*RV)Hx*p^aـ遴A߽knkqL_,+bmf2}!1 .o6oĥͦ*.q}~.t.7L@l!:U7P,'y x6TѝsB?gՠvW ъT Rp\kT"o\3ՍW4,̌: 5Gɨ2ՅZ/ fzjuQ[L)- ⺖.D2%li H$1$ip.(^#R__M'`3Wo*w}#Q?v:~GR/>wgUi+d+2niQ>#}+)|0Zv)ۻLJ7kUÁzh1h|0mɧsy%u˄[~VLGҺ2S[ǟ_62Duirma騻< fnSœ󞙓)] JN(sݷ[MGlQ+D9AB*$32h\tE¥{R{+@NuL$dwG~/ 7g:ׯ"+d^yGL ?GV s+|v>].ԒĝKf޹0`+v5m?˥s/y=wBYH 髓>3oDKKiU ngɵ(OSܛȦ ؒG`eVkh8aPU m^1JftwyˍZ87?'F/DW eL]M6T9Xl_ŊYaaŨ2_Jy nP:Dm(T׻7w'w@)INC~12hIǵ)ȥw{mů>}VOBZ+s_3Ho=. j-K(Ɔ\d L%4W{]:r+lZWpnboxoߢH]CrpKQXhjl(o$OK:Е|گ}Sk!8jsf]@xS,Q?O+?_S3sv0}?-_\k.Ŭ(ܰrV`P4b;Y6 ק併h[-  nUp6.nN㣏.XⴅYgx| x :uiW!qFu=BTPi9 oCiϼ]k&uP]tb$.jpnW,˩- ÎS>r9%Fe|3 so~]7۟pyv֥NpBlUh`xVr')Yteb4| *PfZ:x4͸+צc) ܡbkH\(ù[ya0԰g@ c\xJ#d'JWL|º3/4sNpŰVGp{MDD:Q]Z|9EdXa]wK EҎ 5pyʫtp,)=%f9-ẋW񔗃#]}v`cRkMKYxS3*p fPIoq+i}f8CP]u6-7vzy(s|5Pr!Rnsm7U=>҅>ON4ѫNgmwBZND+)>3<727٦L;((%R;>c5YqJ7_4”꺼z%璖ˆa>]<,FpE^(4K sۓZ{ѣFcr14 J ͹eisp4N Q1uJ4}U~ۚWy?{aY2|HKXΚ1"KaW7RaMےx+ b[lQjn55UmFl$Q ?No֙ %遯CNEv/¯nۥQ^%2?]aRCs6GMwo񞅥5:.]fج;*hY7ɛ0-"ZDFL8]-̊t!)]NiHmmD?1+txOx8^ap.堾("Tʒ{)䭯a3,% 9Uml~YӨTHJ`]#/u)x:' =gz!<9<}Q1Ksi;8wL#>3:uKd^ K_Q&ER-vk) pVy~.c!^ \NF8Q>#?қ߼7y9^t>O:S[^8|H\h)劾]XqiM(U.UEtR^$kLB4CI}7jis.7ŎsTiFzm>7ʀ:ˌ}g1 K;֍FGm%wHc_+GOEұ$2䲩~*,sZe=kMD\􄟭r|a9 c-d7޼fwn>].SBo'/jkcmtc[wmb]BE]3^G=ɔ &ہÂyimATQJG|@BGxGX?pUvw0{Oqe|`;SǍM$(,ᣦT3eP[]MHu_CN1Nko8-$xOgFp8ctDWY&y}X3꺣h=/jy}RwƋ9d pcvk t1X[u ֠6R)0/O %>߻H9ɕB݀P0!McU`;Ee NN63[Rzty\]t|\ҸZO jJI\rp\mݶmZ<5zp@}nS:p^vp}hWdգhDtSvyDL# IPJ"#5ndGiBO=H@MH 숗E|"&B0*PV ŚXٌckWsE9YYvٲȺ )b߈(FIphMabf?7psӀ]GhlG`7$@0M~"0o wK9{wω~Emxl:֦נ+,gr@y*\Kϭ8vQnt}w?}9?\.OyZG@K`͏s?mP9LkS GL@}+bYzyMo4GC" ҖdwQa4 Iι*rLDSDTw谚4 9I410C Utk`y3Ja:VxЙ _}1b`C+Sl}/c9ut,GLj8 H$kydl tܢD!s%Nrvῐr8,-Z$ ,l* 2s>uls5M{+A }?)X27۸FUc`Sg VwX__לVs)l`$\uS-+<~$`c0 -Gph s,W sR0aQGB,lė{g<"; .T8ٚ=2\M^Oh'̶[B£RYD!C]iWr&m:rDQ)}Gf-ZC<ίcNǁ4ΔY,8@' Bヨ ˒Ja&גHNRN9VM6mme~$$LZt- =ii$Fe )d/5\aF0PJMF_2Yͮ&Ծ=y]=2mD bFB. 0ݟB)u*%ӒiUT;~NćޒN-8 m_"2*T1c_RMES\M\E bz* &㑹X*&:)eSGb8gp?G]yO}{ ܇x}VKȌRRꎈ<{0Q۩$ΖC>zl=b{9s%JCBJȞN7$?;̶zI{\(9qd s <qt8,S|QZDP" 3΍l9OM;G)ge|alHR*+A՞`l[GW!(Is&@4/hP}l]$9j_J~VV\o1' R4LLh9r*?"DW)}r޳?oc:s z(>Mdq fb'l+Nx DxiV ޛ2|!/s4cJ=%Ҙ?xo$$tƢQdcVJR.BVY0)d㦖[#oɝyv[c- )ٜ#ܡ0oRGCAO]ٝ'K.RcbY/wO54$>KE3Q?~N@5t{uxpuVɸˡȣFϣh)qQN0K9 vbps)dQ&K*3XE0 ew vggqh%Fk|#TEriGM Q_| C^LBmRww2X`C'Gv/2M"dB!P[yq}GOfԵ>91/5{F ^ tDF@V/F#}_}piz="Gknn^5E/B/щq#D֚f&.E,ɒWL+OZɋ$)$)Ff6 / tߩDQ-GZ$af!# ((! ñPH PHp(d`5dd1kyh*AKPVqO ceP)ZwOa}6@=2v}E8LCC*pð&fr.>\ΟjzdW$zo}ZchB0Y](xg>8js3z&{|p &M;cwERYX lR( %KʘՂ[If9SY9ɧ^¨"F-"K79!#T C7Eean 1!;; 8 @a.0RB`ĉfc6NqBDv%OקaB1w`/TO<]WmoV2H/I\y4Vt?|0^- ~Z3hxP2_s՜2hW MtoYʽXϔ3 KʋrJY3U6b OB@6!&j=:=ĞPR,s 1L', HRM fU M}eg=2 uzs԰\ CvgAye$~OSm3ø\~Υ6:GOR_IJnNmM$4҉d) $K/~er`28[&/䐖<3 I?tNNs2%5y ˇg"ћѪxA`9;MFJޗ{d'P$ѸP#tSjq~>cu/fz)qROe#F|́ r~Ib9G|pyDhnm?eĢx6 Rwg翄F(f8L(TGNJċXGP3,;CK>䲔s[k W:|nz]Zr^OV ϰ8/^@]@|IN!d5x.K4J :(T>fNy6{̇9<+o Db_s_i!x yvVxO%nۧ@p|%OX.Q|:ч7$(!d,t)2h ?G 4/KJOf}vPR7_( HOl&6N_ȼӲd Ԑw<Է: P=2}#>`4A)( RƂL,2#M@] Z3`Lzڏj6wg{ u( $qeG ϢqG<oX$&h',?:'1Y$/HU.`RR2^6^Fƒ,XFq}=_{5gP(]~&E03ջ1"2%3GZSC9׫Q_Ukڃ~ St/5\gVOGnj8{-Wxj{wn|X3!<:5)iݚ! YZFіiaqHxҀ$ e9n[d2JHNR 䚴 V启˨*rN!#CRNFY>mISDZ@:drS {-j $1Nq{tME,jv(me!RF+ْ%mᥤ;B Z``{GxXnK;D 3n )Ę1S%%|:ᮉgl0-~sB 09بC WsZmֵm[C?(.%_&Ht pvF36XMięE>BڹνXC-@vpHѳQmnӂJ񮔀2:cDŽ)Fp3%M=-^ +y=:瘹8P$ۖ$,jଖTRnI{? ^` .S%L{œS?ԙ6D,p*6~8};Pv }xJNMw["2FD<wߥR^0IRS9&vX•dvni5M]Er jqa쐏X6]/ ` TUezawH?7!A Ԯ̀ OHA"猞qre_XPPBA&F[ W^{[rr"n qK Y:(wsI" ` 'LPv@1,*XɲhJ7G1HR~4f|-Le4[ mPP@0Ȉlw)yNL=8[U>Rj^`d\+Yz baj" TF6ƽ=P0 .~tdJnic\*kUzs'I5 7;{3aKΥ9:,qQX'C8zjgvS2#o&Xٞ"afTM/[9ubj}x'V죠}2M%i "u`7ćC,C@>*aNQr8`L'@.n9z+7aZnq v< "oB BN4G$lnm8oZڶC&ʥ@ ] 9Z_0+$ʙJKTŘa9JI0IH KcdR[ )JQʜEe[-1 ;<5NgS=5SޟVz9Q7LtoggFTg4w'2Y6ˈwx 3i@09 izKDFscƮ$.bQ1K6Vg+4ugmm=o׺mDI.aEmd, =$ 1'vheG2pQ2s,zj#] eu/q02gǘIlXGꨢ8Oᩦn#f0ޣM>sѳW^&i-tbKr`u1uBAʕ[ Ǽu>,U7I|kVPlipǏFNNwĚ Ȉmݜ{n4,?E f&(q ZNZW̅I5"B(HT`tN!KU$%\.M36%`A2+UMS 9"E qom Y4%1o=esYeJ&_™O;(73|A9ټo-{71\ɍOi4qѾ@ĹZ J_t!n.q+ސ84sW5W`sƟHlp~(.$3dWɍc7HR(߸">Le>*]B#^.~#[#CHwnoO(ZžڙK"ŗ]+UG i4N9~nM5p)wvH Y/gB,5Mu'#Hu6\q@e \!.R$RcF F5$: }{m;q*>K XЕ]'Rsg\~?yw64-6[P>o}ڪ:=g7'ĭ`}IDY*gw9M^`2~)Jw 5Kst[ ^iBYp&]q]k;daƤ*db YOiTZX"4Ar;v` `.3L配=Z݂FMA7)G,#LQdxϞ7Ӷ5Jc9VUB}y5 f ]Iԅm A0I0 v EIg`8Џj|IzF:AĔ:;^m'.:#C#2-}4~(9mې5睉 |;L#$`Ckdnb/vy^^vj!8yL`'0_8>8صĻ|N^g9)X$5J)4+#/O#>UD}M5/q7ɟFk2qhq=RT^-fyʂL.Jмx ݨWjmCtSKUze _UE><ҧWW_am,C#$8FHp᭮=]xsyRJw]UJS5ys*=|oQA-̩t{JP6%gBSGiҼ-㹞Jm`kBh_ SpWǽ^:p!}oFJOc!!0BC`//]QlӇ7prJwwf!G^@CnpkmG*uC~;PiAse9$g=ؐ}tUڥ-?M\e_=;uЇWʁ_Ҿ pUʛC` #$|SyrJ1=ՀJJWM UeMzZ-mmc]Ski0Yui/iJ?Mcm$~&.$s0G߯gq Rys!!0BC`7*OGJkX6Ψt2t4SB6[\^M C2Ic#f.h88qA (v &L Zh\MbkQQYsz$RƝY{-=,n!ĚJ A+o#$8FHp}O?>04'Ϫ*zrPLb-@2G&m>lMʷ߇QI_,Lq^KtuV1ѷP1"mS(}V[j{ϼ N !0BC` S@ ؀<KNJoUh o0SdMd MvfkSg˄u4OG|) |fkZϬ<3{<a|><=q[8x0¶ l o#$8FHp6}|SgQ]A;wWAJ3}Xuc9\TZ f% 5M tW t93Wmo<YaZ (wBˏnN܃6>f/įg7 #$8FxO,gnG^JClMX=ai-}gWVJ}WT:@g#lbi ]p>a֢ŝ<M=Ncfm&ٳ`ͣ젏Rח7 #$8Fxs>?ZJ:(yUZg8+T4G1z3P)'k*~?kT tk M# odE:ǦPn:E{[NkH|./ni!fNȆ@` #z%華{Ww;`ަJR57pX*+X!vDƔ ~_|xt)ow@}36 'sVgR:)pd !,o#$8FHp쒹Zey†2g4< U:obQSy?WipV9Ͻ8lLq m4P::L)Bzԧvh}eْ=E'\M殞J ob% !0BC`oHUe֨*}2bѥpf{ UpB,Jh}P+ If&+O hOF h@bky j~ w7`{C.VuIa~МZ! !0BC`]T"mށG0؋ZhYB+ z]_0lR-|ҷfH/ H GZV)OT|VC#$8FHp}xWn rwS(?Ptk6>TzVhuCx&]}(0M^fFvwO?0Z$AnU<^59u$(|4Q:lAoa:ҌZ #$8Fxwn< 3/ӭ;WUȶ#$r~; B[_saJENp<]iF/(<\Z@Ai ~z}҇5 PrN)f3Nou;(c wfs3=s@ 0@C` ۧn[< Q;*9~3@{z 2jY eGҺC7iCI$gȹS΅/npCZ$ښñ*h?ZOHuSE tJHGuHP89Oqn;U#$8FHpu;p*={XOaU"R&tu)hL1ۏgo8yDK؋\G9FHp!!0›=lq,q.gˇP Bcoa1ϲ})m4J=,ML[4)ߪA,YR Q:1HdNS*XjL8Md #ic*ёEO0LNFcH/H8--H]s*nO}*G.FYBKf@mKڬNi٨q7`;ʨcч0B>@ʛC` #($PUAϋGqyt2Lx)>82fr43RJ^GPP@1I^,I$N{DG8•3V5!Vq -g)e֫4!0BC` ސ-"yb1Ka>fͿԆRXm 1#k1A 纶=z~C#0OK4*!fKPgg,FEM,:\"o#$8FHpo% !RmIENDB`gift-0.2.0/testdata/dst_resize.png000066400000000000000000000307641513354670200171540ustar00rootroot00000000000000PNG  IHDRdC)71IDATxLٓ-qZUg~ V 7Q(,M3#~O~ $&R&H3,ַVշe:2ܾݧOU/czÂ@bhklMT.BKsk(Wjg`Y[qwY8jS*ϟ@bsʊi5g3ZS H53U{5^^vy~몷n4u]8IM+ [ZœM7x*n:m*@X͖ݽu/[ .ZZ'gzxvN7xMcjnn)iɴjFwα%qLݽDŽRMV E!m`#0J!~G 4(-a!Ǣ*MAuON^׾'N6_έo2ƢSUJO6~~{_{nR+:vc"mUcήfO>?qI` &}ܽyդٿEU'>wڗ.u!܇vc{L;WygVl$6^7n6ݚ.*( $"e[YEXس@& ـє2 5s6S9.N }8 ިxրFK؄R](Q!ǕXIqcUuU9ʺhˏGZ^<}݃km*_ݛ[͛o\۾?Ւ>'w>, XДR0PNspUVd]]0ǒ lQRar}յԡL]WMS׾.x\FS{5/jP_>dZbxXc>qD(g]UML>T3`g\wݬkLqs-|s dCOG=xsN$0LUNISM3߸wpjFخmvs_0cT[uU7M=5#D<Yƭ"1MqQ݌zUU9q+>|m]땶)p4X]6K,RƣifZV|DଫF{rt"1c?m\3re5u:yo\>'̨vv;# Q(ݬlwV$<9.NE r〒`XW׍uYlo03 i2( Tq6ml3FjRV&UtҰ[4/Ξ-^'s"Elzs !L%;9;y]}89o毼f KB4Bе[-&HˠNJ-sM64($чFw^~5< ZCYoެGvXR Hg}XZ׌o\>?;TJו/={`TH0h\bٽ[ZsU`oaѓ;|/siph g]J )UV뒣 p"=i#(9򞹯e-9Hwr,hx/_=ɹfL!s`@.֧Kg VPW>"KQ.۶`vϻ֚jڨ槗 mk9,,f܇SO@V:|NIźD ;+h K9Ue,3]V&"\ YLRH[z_9q%y79}ujȞɊi jNu*7(X_D/}MDvP \].lbljts?W>tR1Sjv~є+sȁSPJ z5ؕĎ`++ϡnqD+ 80V)}Zu {[CNedy,5qUy%ᥤ4mvcΗyW#&D }2Uֺ;ac=yR)FB !ꨌI1pҺY4e%/ߒƧD 1eҠ}5;1J)^ Bi흩ĭDjo|v1,0dh \.gMk[F+*lo>G}iG w~?Z/uX3aʡ5j~=}jlloZ6ݱ¸v1眑,|UcFǮ5]ǻ6呔SfbaWtA(,O>xdr7@(*_~R1/:;;c,Qhp)f4)n{pmfP(oݻK  |O<~Qef4Ur \ͥsIRH1o]ZCΏu- $C9{a ( ufk++/UCRX On)ˆTR*[߰@vmc?6`nמ:{wn߼{x7QJQ-N ޼NU"V=!hvy2T,I2 ]UJ*+&%eA,IbC{9r ̐I ?Ktw f6=A+UM&j۷݅dhktx8W1$\dEWB1>||jx6 hb,@iy R,X ^nT~q@iGM`=XvzD",2"g>u m=S=MERo4BaGBll(3 =$-õ۵*gTkL̹G0fd;j;etqխ Q3u`z'_4#@s",/ H$)&`FUЃnmw'=Rq3?٥pn*%ŜA0MQq#mA+6iVC Et'E#?shwדXbh a~Ki^ٞ4g3,B?~yv'3IPXW㺚f>R y2qC 7Uy;i4Mz^>~=n~|xM,'JI2;S$E35Fd@#8cTJ)ŔB1K-^57i_ ICYBB3󋓦mm0nX/ϟ78tormN'"(-D14jbp"qu4dFx2{=C{'ߝ:^g{)RNAdy.'"r\CLQ!2Juj `˙ͺ roՓ }6J~xct5ǿ+֣f5ڽso/X wڌX5zbcKfjk̗HU?JqwbOn2ݻ{ǟ(j_],Su o~zf!>ocbM؈YIAa(KEa zSL1s`Mhv۳/_4i^P/cj};7ޜ^콵X_~.O8nFUUk㼯n5u9[Uh.B Yg\Nzr`wkCK]sskk_z3wW~| ?>iNbԷ%OSF\ʨTuJEΡShT1V蘤ʱ>}1ͷY_u90ܻvSO7S 9OC^]>={zdKu8hΗ[~9_.V/n5oOF!-rX^$Փ>EW^_vP?iGOr{J_KUO|$c}L}WҦ6bcM3,ؕ጗ W0~/WaUdzH?lW]}v_f̫?aVwWSN  /f Nbnh+; (jw`|ϟ}/?X/&;JVo}9(K6OBu|y-9ޭG)K0Ɗ,,j\ǾmUXª` jc Qe4F's5lXs0 R]70)0QSOG꧿n6]njt)Bo}; g[-gOxU4ly<\|"վ-矒hC ëgRئ0/Q5N/.{_}|u Tw}ZY0z펾s]SYd[]u@k*뜵iXbR*bWPcL!zPWj b RoqR ,&y|p?\iP;z8;4QRG3%D C)+X/E񔘃_SdWp|ɣ)uz97zY1gEUXNhQ6 e9b:P`:=m eYA K lX)P.<]m(OB%/neaIwLEkS7Cr{9)_PC~\׻˥pn~꛰6|㛫ǛQTOwS;-2x)Q[m;)oJkj닅@>=\uR\9ŲuU{e4)@)l(21?UY:Ѿ'C/ Lh%3ll"H~Bb$D) fDsC(4=Y?=oY3 ͆0 9irA)Vkg3j+s})'JDuՈX, %V hb?>\7d>P28LBݏ^o.P ꜴYH Ҷ6TRLmJ%QʽXŰ}M=i꩷5l/zb_h3}ubX fsJs)֨᨜sFWYoƂ)SȘBCW!xB尧ӂxֳxx~z^1-l~ 1[=oT2HYe SS{>%qV!ՃT~6ښT~qa>@0lf^;fs W8QvK;rZ;kQCTPٔX"Z8UM8LrPv}tBٺֶ/(=2~tRck"'d ! tIў=\,4+kFx67Y]ԛh{{pi۳w߾|L9T8%){^58` K*CKF!͞#%+|L5_k~KZߘo5.`AԦ i#e  F-$ýRǒF#A!]>Y-Nz(MQ}XC lK)7bڽ7{iȌL=SrKa@r,Yʅcꉙ2CS 彡o#Ϩ/}Y~ġW4,\?:?;~ڭрzdݦ֥$ICc@00! GRevFϦi8/dgfoTSڬ:5rn:n Y#}|{ "oZk( VQJ̽eN{"ų0rfKcUނjW}|hk%ܪL:8񲋀Vr&Ha\cx F_ezt{2ɼ<{xx|S׮/~Zݜܪ;ffCLU5gCEU w֙D}( f)9@fٿLI'Rٜԍs2ISRJEEJ$Hѱ0$*GqGS7B \Z\xο:r!{eW$@fSq9ZjFh4&9#3y}ng`-=-h!dUv&eTy ۓ.lӮN2HgL[l7)*II1zZJ]PbX͂GfdI9Af P3ʊҝ$g=2)RҾQ%͎gxX3j̎ ce0f. pRN.F32UͶ j %B0 Ld+|or^1Mc IhX.7vQڿX5J"CY%kPkHB @Y( , Ia"GO^ #rVb|,-3LdQ,A>Oa!&CWsJFG ̗H)L  2f,7w T-[vV0v(=jqĂwVr e\՛ds@+ĢY˅gj^Ν0 StԬs9O2ha:u::>??Kd݈M Cb-Z7EDmP !0Ac=i= pVYPTH;^:2)\ȱL1 rEĄQ[0{b1ʐxj^:Ԋeȓ}l+댮Z N[JYZ`SWCybLRǣzJF֮ 1,.2Ϳ(On)rbC ST|aA'g8eA>, 94YCJ۸aFj8IgSH9-*}Z]}4Z \վɱSNAp h˗RML,sIlꃔ 43C):mlNJJ;g5ȺI93XǀjoJŖʮ0"P = dZGLveOKDKA1Aف0aG[כt61 k-ت[].QC@l&O0E+mɜd/7] y)ee1^;YuŔ8d{ۉuȻJW9k;N$YJ꧒ "ї-'WidLecΚA0-D!:SrM}8;ݽã'?xQDq.ZnBoܹ9 ;Qޣ󨪽qrʀegj\SQd xs>uDIfKĜeKaڰ$WW}L i1Yט:ܪ`J2E~.|([nBWJ+J%1k|W]%s)gt|}odhD)֬o؍9OYW6H I,ubض}CQCf1^>[ꌕ5P;x/IB褊+]|FdEhJMXБB$GC_6E͇%2`N0}L_]դ2;V3hٴ_RZb3ȰWU=(ak2w+I!}軾_w]1'M%h4ŔEis1tKv*Rd B+lQᤔ-X"uԑ&`7fi)C|-5,]^̠0ҥʜ^arѺ_w&ZJgPc-u.lfc"A%ee ʼnJtRLo~e^-{QiD%%v)D?(V)R&[1\pXXy3u(bX!PCV"O4 cb׮d,9mʔcQ\aX LKHr@6`PHP:5|@\BJ} 1mZmVͺR ,e|\1ZU\e&L (g74~0,g[ !GI6-YHJquT ml9̇D d#:L@ lǔ8OUH{{lLYƀjhR{⬗Ra@ ݬ6u1Ĝ(#10u361ͰgZZj(Eaߜ< 00| (CWV*W[̈́-X]Ԧ]W^.ʧ])4V=\Q L5@-AD=B7Cla?NpeK u]w}cD& >9k| &j&Z!hJ?s̺IENDB`gift-0.2.0/testdata/dst_rotate_180.png000066400000000000000000001036201513354670200175310ustar00rootroot00000000000000PNG  IHDRxԅOIDATxLٯeYrǰs͛SlvlR?HJ"O0dYG͛V`_(6*E $rj (7@]_m 0ٛ%=-IXu\aطm"K0M3gH;.jh4 H)2PDfLjD)'%TM–!vDB5sf?O]gx X[sUQ.f-,P'=axQuWcCCޮ&E$3*s(k̦@:'DW-ەt܀m[` G`LT)e3)<|Fa.bNvܚ0SYKSs+1Ǣ?eG3\{Td0W0$L(5ZhP8on/6BN)#%ENd# ə4V=<xLPAh)!7BShlr%:*8FM19J\ CUֵ5@%F`7-p33VU(#6h/ IW{XʜbZŤk,N 5upmDz{ik9usIZ,p'm]jM$skp ==jO$' gCOp`Tgơg,34aJEC;aώzpm:OV}X]æSGGUr& Xgh,%5U> w̨"7ثdQB/Wvb.205"6҈ԝo=#7%NiM]Bjbb]2q3ْPB3d[FS1e]2q.y3޻ExD] t p(a5$;HX1@Scߊ`nۜFZa:K .} >>=d@4kl lMh]g7kp{[ [zkZ-6h' 1z{pbfbH7O1@U+BՕs0҃y_sl<5%JΉKᔲ X$ǝG&t=mp GOG÷dd"j_ho""5"H,M 4c3䋫! &\|KmzT8]$#,,3`=w P\L=1g,.|/Pgu8~EH:9̄- ) c\?sHb3H gV!SX3@P{چGD$liHh=w PŖۧWu/n.DDlY15]YW0ڛ;2EAhvZ=!񫗳=6j1 Oy<ՠ#@B:); # $P rZ=ؒ#Ķ JM=]%NFHsX#V&doR:#餌8c]S̤R<6I^awN Cz*7YD[ե_bϭ50j7FZEVh4Gy&j7[Cu][Y{.̼lYeonϧfs2&hs~K)9Ea 87lEԓ!XιE%wDөQEO@654GcXU%#`U=*{II5 &2-g6؄<=Q>2ofx§9Gs?r ĨUfF;c#mdlvwָHo8v[^WizԶ4ld(pmUYIׂ{NW|ۛ,Q[k![O@(ӮS.MZX'Z[D 9@$7G`N=jH{m)x:v$HzY?O|0Pq̉I9s{pjHϚy̜jT )$Ulj~>f/C境>tN}s ܧn3U&-b׾6/z=j.Kjkk2U +5p^>%Nw柴mtT593a.3g_!_?9ߝi蚩4 ^G=90|ovꍹa z*|*GFŇ?eMӮ33Qitl!LQ< #kuAh$6Wxˈq ZNk<7h7bBrJqGB=3_mailhB޿<'e39SN4ӳǷr<.٥wHVञ41F~SGZ=mvnc.ir^d'!k/* `q MDZ0=Nt"`#8pەQhPt0O'ۄ'[8T[ȣ!C:#Sm;W]jnsD־TiۍZVj]׮܉`BZ(Fxa O3 ƽW+Tb(zʛ Ω\bH&Gkw( =,qyןUCwoiVׅƷcB Bzb 9Mm/Z% (%5]m;v-CǧCCY7nNeUB&ϔpLSC80d*5ζ'K|P} '08Dվ4h6V@k5 nG9ɋU#^1pt<p=%7QhVBbg'Ϟ'r< 6d7;O_~dFTG48G+4JB@nNi*i9A!Kz۵nnnZ{k%%C!fJ-3WH6#WVzA:-57z(BVs?}$e)y)^ XJ$KOOfNAECtb>M24{h$ecJwzXc]]i @$4T$Ξ T#q$ [<0P8Cj:hq!tk4wNi!j{T8 3$\:8 p3~]]7|\fľyImZ]@EN=g>cdlB\1H8,"W ˋ[sg.eO@Wc=NQO\T1٨ІIӓGgb{6Y=E@ &?l뺿_nMN`Hk42~qx*{*hd¨L Qz^a/;4vFZpޘvuї!kRwe?UiެZOZ_1 ^D_XE h٧EֻGxm ާEc aS!&Q=RsAK[ʜVϴH3wE'ٝlۦr7jjl V^6^!0uTF%NW,i% G݂B\A{NSSj)Pp'(h1JPpD7̛ۨilm9S۴zUw#Tg/޼xҢc`rҕ84Q܉&e= zsvY$M'wx䁟@#gv$kW.},L$&J Y(b؟&7RzLB+$6e#] <@ȳęY╼/b ;'JEi? !&Aăj_=bG˙ߺ㺤s5ށ^4GS'գhEE/xԇW"i" "e {@+Y>x+F,- 57PoI}ݜQ7KIUJC) aݯ@p?qH޴>,z,R Jzߓp=`eՒS{:%O:i{dw݃E!Fmc0M| {p ~` P(qE"/6#tpX¨7D)UOjR[=^rЄqP ,4Dzϝ$J՚LD&@ODۻBmU[FR )`>$jw$.I9eU!Z0!ٻc} U;[YE <>!{]V]H:3*4)R&C9j1s*ptai4i%MU>Y6|q~Iy.-ESb`kJ] =e{H${EGIX0C޾ ZǮyq"ּ.qps8ijC#}=m '<=M-x) PH>tMR@Yg{J|"jaQhovC`,# ger^k|&4bdwbӖQϘ ܺ<:u ⯞F$%Q2+9-sIӴv.s^sb&À7NWiм얢 ē:STh(Á(&Qit|5n}Ԯ|]jyPF+]`h/xԓFf=57#{0IxhAu*0j^:w_us&r}4MaZ*ޯ'J{H:1HgsOt{t~ټIjSDUI沙79!s˺JgifVY9*W#5|2n4}8`fCCku|`Gnr$ѱ " KXt2a# T 9f&+цekFs%TcΒ!S54BUxNŰcGR\Sٕ))Ohw?Ш[MSHgR6cAdlwgvsN39oooGl=e4T @*-ZFe}R>jBacbv@4 "53FK&:ܵAHc 8lE_)zKznː@wUs!" +#Ǥ(Q9[^Y@ zM`wd 9WdﶋB;2.cR}*eR^"&J3L&ow}Hg]۔ ݱ/ޑy.S%OevyS߲+<q{,ǵIl覲#fE}HHk"Z*0K==6ƃp㑲:1AT[ܵ$EY"(d!nc~'BC ]rۥ1f0c&/FŒGvF|0᭔O%eNpj/B_v-f%H^~݋ú11ON.r~{{sU紙7ǖ-*4K[YĈa( H)# BUqө7o5к$[Շ< cJ]2 ڸk^onhqz| yLRxQxC}s>wضf 1TC)g.>.R2uaxf+iѝjWm=zM C$ix#;bU&ֵR:TB֥i־N'=dkhRduWׯnnoDPWMJ1ѻe`(3/`@HJu Eq@?I\& CdySGf1,ghPb.;=\a}z.ٽ r<:+Rx `X"G*VSJ03я SֺxVL E)%LVbRbyiHgs][;]ZWݗ]̵xXaM\<>d|Ե]yam{ԩ8U:SWQStħQd/`@Fm{MGo4UE@h7Yc `!Jࢤ_\^e ۭ0PXd[ps{Hn)^h9рƀ!\!wwv[F@Na|Qw}!1PGb-L$2QQ&퇌Smmj=\ʾ&õ$ؖuʹ!k> I]u}}f}s=\>o'=;O[:S\$nwwׯ__ܵŖ,W7/i9PTR96uo9s}(le FtyʊD&PfF8\[ 4vL: o-;`@`5Q닋 1b$4pc6M⩯s80YDx W#o!Gz'K !F7 y^7ׂ&9ꝘKIurߧskӼr "9ϵ67-1vܼTT,49>;W3ec}&\ұ8ٸ1s 9/:S[S*(T\ rC(}ҥn޿x?/~E쓳G82ݬ2{t;x8$zh\ qqёpI4 ƨ!פhͶ |} $u9a1Jٗ?8ѯ-_?g:?~lZDҎS/Q޳oxJ&M9k**Qh0O۩̗s92Ҝ7ɵO8Xi0J3dz|Lj>~H>-UG6LC|:I}/gۧo3?{\ZoOg_M6^QGz(vsc>u4?;^:.^Re.cR9f*{{+ wյux}~5q9yc2|'p2-5Kz-[2bMy}sՁ Lbwv,) f1o p,vP|\R/أ-10P_'x6Gd(tXn6z{ڞ~RYZ"̴@)#\=ĉ'99L%miE+9؉ɖ3Yb~8Gs5 O߇4Tyӯ=C(>1Cc(ϧSdL7Tyѱ}6 3ˇw~f R*魷{0"D>ޭ>ɮH?qEĊS>Fl=_Bxt_UJ}k S>,1)QwM]7mz#ڣ~Bu[>k#D =)NȉS9S /yWWH׮1s*I)Իs8 /c:mXMfo}t!>:ep{ZaT>ه^7+I`O`5SiBʾ \y"o593{zwً r}ζQ]X6s.>8>ll!'cMS)[ʓ.>iyF^@1 9ni8kp^,;}~ѻ<y&Jl/D\c۰:;1n۲0GQЋR>'}|GʌS !.<>᧑iȉ# RKX%/vYLI@ ^hS#9O)ijRJ ;hC-9 `- 7+?ψ|Z߄O?]mKK~#Ȑ0WOp9B~:Mʙc״Vc(lR;rz ~pP-bt鯒ړRV\n+=K!Ed{'ͻ6਼SIDxݢqQ~qj ~IASkB.qmiL: 8tjnpAW 3@&X;,G2>ETmi ck ]7yv<ߐtiQg`HHAC>zƑG^ofǠERH qQL\pBc8vKGqv"B}{Ώ.şKLB!.>n |cȗ x$}~'+Z=?͙I6|Sr~;wsؔca?.Vk IHݻO‡|h!+|x˯?? mwFMi;oLiVڼ4at 3ВPHyL|N>S:c7lB3,6 \"]}yyIs[s{-Wߟc ŌEqkH pd?i5-4$H1AOp+u5aiZ#FǸQF3c'?g{\aBe\0sقTJv/{?ĩ (\)o6~_b?jqx1֧їmO6,(+`Bwi c 0V[϶mwkz}SY\Ș\zL>qĀ >"S` ֋Nˈ!_"Q.)n}CguE )mJ2)AKiRzJTF^~?/"O6_%oko?᏿n37,eڴ~Gbъ)d7zJ8 sJ:JxaH1:^uqmiWeLCRR}ESlɇ:hڼ?p[.ExLM*;ԳcYqNWÓkN v_OG]G໗~Q;MM:֬fS4g%CZ G\@>7M.et{xieNA\{Rvm7NdJaxtqoO1~CяKP߻<>)1?Qvy:t6}jĬ̔|Bnݰ9D݂@.7g'ͷVH>Geە\Mggeh:tٟ/ܾ>yW7 Zן~qk_-{O)Lgw|s'EtǴ' q$i⍻8(cd"bxEnFӗtSe\58>% .y21>l.i k.S'p>.{8Oz?o˔tígDT6)Ogcj]SN ө=\ڢ7NMR]ωe"kUi*<"kBHS2,_.MOA;c {?mProoo^߾:Tʦ<}ooC[ևR3R[n}eM.->j]|[-kiJ^o2a:C@8)|aȣO}Y[lJ&+1/گp8ħ`OE.7=~lڝ_g߀o|&\Ro/>]?{%Px8aS%4^v[6CWJ]O;36800Τ{U H69[K)U㛫˕t aR'}EXHh+Og84g_ۥޟٴsr*C~wok_jTl=˷on]+\_sV}>O7oO_:jw~KgO}x18L[5~|GǗ|/o$C}@c,zߴE>z~6,b5QFɗG]2smrR'D*sBӇ?#zoTeBlK]vE~oO_;wc}r66XxyNٽ1˘4N)y3lޓBMGׇ)t©'H*D JO6y32y6o -OGh # l;̊Vrq)}zIu8'yp*4%`?z/5nz #tvSu럽p7S&u$ֻ$fsi"%д$?}q?++?u=b3A=?D{gg/WRHٽn\]<]~T{Kٌ3~)q.i*>\jyUs]ow˲.dQzʹ.Bէ<9XoziЀ^~ட!K">ݼ.Ǜm~ݟ_|i|hi7R0(H1%9=f~=B^5ם7?w~?,O|Q7xǀ_Il|ʥ0o?,=s7ʩ*AlRI34MZ~- ؀a0~[$0(A"%nTUYYS 7g^k(JbfvVDs^{ ;y޿֢ AS $Hǚ eh.t%0,(SHqW\Ƨ/ϡ⊤}S*$ˠ\XO A xkbZU GKT*JU0z?Eh|dzo?cO{7OY=r[&xJCnqC{&RUDGP5:A^T^|5:߭4δ.Χ;ry\˃_zzQ9#T @AѤT%GjJ!*ak-w~{Wv<쎤PQ[B]J#&i}:A)y|vk6:WhεGv4z7(WJB0x n 8D t+z-xd<8R 9߲}ջ?[Pd"yIjM[&r -O&30\TD%T0U1 -MK֑'+Y4H0mP;v8D-+KvIάM-#s{"Jq%J͢)/^ӂZsQ˸(J?(^n'|[u^g?){R8('R>fֵ]S+.6F&I6{X:<}MRZJ(#sU*@[\*&- ַPô:UJ~?o?ÓФMMr"Á|<9z' '|ngGɟ%$`aMi!tL mWwm'f(szpK%SM`ivT*4̑fTHh$14BT|xQC.{ 3A6B0˃wΑm,uˆBcB ܀B *IKQί{ksA~BٶJ=N-]esof$IzƂLψqٛ vR-=]?@e[{BH qG/ldGnˀRWUO64<GOgRձ;ij{?Ooo԰IF?XTћ_uǣ^ղ)%kcEQws)Rk`+6(Gs&nNvrA%ĪLVHBBp)XO(˔}Cy$qa2{lRҜ) 9PHS-`d'ZUY=*ӗgϙ02W]YݮnkDm1`\1)m.o.NahՠIjtds煔U޷GH޼?|4niG.):'=$<ȖpGGHQ@ n[Wd"S|㶑Ya8xhR͔VGn3Lʃx<0߶݆I^bd\)]||Kosv:7WRG'oRb/"H( e_4sc%i0 y}*1c.V ]JCx6̯/Ik:48zTU`ZUtO!"cSg$-5OE;^&yMfYx礐} zMdcHbe8Gam74<#Mٗ_uەNrvV\\OSTs⭽~#i?Ǽ PP3~k̳MG-*C\ii} dlBXU!ِRmS5*: !-ǧ"W?aT- Sƅ=:/B$!كz77)cL*ת3i&ZJmuw{S)IkQ2EC%y&RD"[0BhJ?(1z"fYSBG?IA ҵ_Rz>ݩeA ̇BײF\?}}뷃s]m`Lyu7CgWh@+lh!,6~߂ $כDrm%cԦZ-f3؆Š{SAJޔbt`xv Ώk]-oCt:Yi/?HC & =(EI\c`*at/Xlw}78|}_g뫗fXߴ VA1筬uI6B [-Sm(L;XI"!( j84cK׈MmR9pI۸` GL`@cuZP.UlP7! -B6Ů݌/^\~k3'A%BNSqp>e Tz(KYD]ˎQJ9DP,#B[Mb+ JC4Rzᐒ$HTb zh Д}@ǔ "7;rٝ[߿/82@%U T4Iコ@X$H(cY&(J=$ZHe X\pJ;< =xD|BڲYE{2jʿjɯ ,̟=1Q~` U1ZN@օYr!n\jAjh46H̴}҃BWU9!fg9q@HMg+ME$L3fIYj~&aY\/20S*sBSVQ)&%vZ^MgBVQD& =I]E;$"0+U\ӅΡ5VuѐG[1*9|wft~ÃFUBk]yۛpzRnBAba:ƈS4B+CRU"]3TUl6h0pub)sldf)p`7hWz‘$hY):ɨRqȞʒ dPLpI{=y{Υ~QM2 rb]~{$0 R H+^>FjUVG.SuZ!vD:^6ؖF).kmv>|w=Vs%GWN)Ĩ }ǵd!B/+* :>>j&58aKZ*GbE)BZkkd962#wT9<>$CXz C)eg֓wA?$yg[s(Y/H_OȬğFRR-eKb)evK2"|en`2 q֫E&!,M={m;ڦn]]ow)SblV)<8~2) ]P1 $}8ҳ3 dڏNK]ٮ! D~2=]m67i,vnT9nVc%!X:_G6[uQ4~<ϭ̊=5  䲉'ezL9(FAT @ '=j0XsD#pK.1]kCP3Od)dNַ5[ɿ +|&Y&ԹSQ.nLɃ'+X1u;m}AR#ڥz[9 ?T¹yVby /L`zn]]HՃtX.x7Ũ 4hRXm, mq~x: O˟c礊—CϥwŪER:i /$~j\O:Řh  M YR Ţc{&FN!(|yCD7'@E@ Wz$&'BafS%fު(>XO\$wK18gQONHآ$DIZ2SVc-d{Zv@F(=/R 56U-i+.1JSCv3ھ}׮uux0)Ѓ.J S7=O.rlpow׿0۔ż/Xv1̢JwIY" *nj @QCpJ0cBIH$ԧ<^Lp*;*G6nEQ1F!NYvJ zI:m(eӤ\=(+UjW/b2?b,Mc۵u)2Cݡ@%@Y^jUҨHjaJ6O7r!Ȓ{^衒&+N**6+c)qmcpY9*+ISR lWoF񵍺fI(.RR} 8VA=N>G Er{^rbA{z@Fs5Zww>5KwO tGJUҚvS)qU#Ց-ۭ2џqiL`"R$9?5\y=DHqvIWE=KgQJYh6 Lu2S7+:=}b~0QSfΚH If_{)ը -Gݠ;x?ͮY.[`A*㠫x,VZVS3_I=S][r;C~'/SȚ!;S05O H?$xЇ^#[Ȑ &zǻffwY"aӢA*Ύ?ض޺"h)62BOJn,X!t*K$z;% EphLU9˫Pͭ,:=C.J~씣ԽQ S@̴HŕҀlcy4=e/66 L)zsij0L=j8xx*!jyJ`PB0$?WѹЯ\9xvw˗mWAn, S)rKu(Rm:q4HډYT4gj{񟾜@6$Mhߗ!ljHcw'3y#Fd:r|p$vi?jm"(e*4#U`rQJ6fzp r *1mǼ%D1@dh #:= vZ ,XUR:f`Rgm,uzb!/ƈCSºt&2"ihBkxac6Pj<ΖdX;8,ـa<@ꤸP!|pD7r8ڹM ~dz)J3ID.*A w+ /a}8sAB} ~[A~bFC%},JE^HhMRSWS4{&'rKMO.JTex\LGSfѡrd$@2jCt_H$mcAߙK ?M5}@z*pY @+@)UDB41d#t`}qIA ii._04i Rci+KY+ET{H9/ZsAˡ ZSq<>:L5v\A+hYǙ68l.u\*%ڱ0N R6c@Hk;!D$= (x!].t~8F'ŧ  =ۃD'5"SѲ[9ױȜ}=rޡp`@+ԭ DBa ̗~H"XĂ*]4-+RA<ÅQ.x\IVѠ=…&qTB kwVcv#9EtU&x%a~:ɋEu7T4#1,6Zh5\WHyn}4CY()VzPZJjQ8ZSDd*rQx\|._ m1=Pհ5yGT =9B ,wmF4[k[`0vUY 罧4R~D x<+̓)Vm,DD俇 >[Sz7S.iA^ʌ!:Q$T[%f9k!.!zdXH ϕw|97FY5}?qvVq:`1a9@͹V>4BZZH/#g'ΔFo"}Q,dB"v=K> vW7ȧP^!N%&No޾/,Aaݮa(x؛}qo-baY/{5 9o9:g?u[lg0HmzX2>m9Is-b2"gq7&C ǧpvml"4:j"!H%붑N^|TN?EZPfBko>^9kmZygkknںmoxŎR: ^ 1&bR*le<2OfwAI"2Az{'w>H"՗G%+ 5B+P֭E^\c(E6=y+{ͽfV}ą98dA%٫Npgε֡@ ( tD~=d_,|$0)ke츴Jv@McݵblL9J׵λ_nTo|G_|m C $S,7Ə5dhR 9B=\}N眛՛vt 6p,z3}Y~ʃ8C 0rz~7Fw/ Zs'8#j7~엷G`ڬBay)){Zntϻtݧ(x8=gz32]]LqE v@DF`"Jf(3$;R{,%C4eQU]IϠc46}8!j=(Lũ," -vYOC  )`k,9lY3 Fzfc[osZ\ b*tm[ѷlh??*9JspE( yQq9<-B/J*Cn"5^ގ2Pf&xx!^Mz~:{/*C3. !`ifcgPM&6h7Mfe5l-% d1$c&/BGAL%u :u6<!z - زH#BW4Rd(G0C Wr` .-RZ!3rp`r*pX斆DεXjRq>u^^,nvbT 15vʊ*H:HRF+jn^^A@u B0(R.;L载r$pt쇝`,hvrXNGE9KYD-lvJ*Y &W7zP^]UÒI0(  )J*aQ1?N(% 2A4`ƳЎb@\H=tȅBK6@B,6z]LFv4f1:UlB) "8J>u(]]ŜA=p@, iv@g䠄:nBHr? n| Tj3BA\gc[<.w\M/j`-, ~+z0.$`.2e!(DVLNgnіfI"2I亁f.aA4mޕ`F}R" g)nB!E,mO߼}??8)EI!R@UUOrv}-{h0+3fc8X,t͐UB%R޼rw}k-ƤCde6WX !((OCL'LE>p0 :L<)f׻{ZDJCE\EkvG*2Ĵ@Ԗb␕aw$'tܟsi{HvbK1hlwh~vnwS{9gu[;+!xM+4!" "}ܮu{ }TI?)JaPUugA(#]) [=+1٥I\VBRBJ+!Ta|~7(jI[:O@<2%F,qf*łw4Ejp~ʶm..gO2;J}}RKp,ejP 5dO~ )H,MzSa A?o:X44KGv3~y &D: (M pbS7^m:P]Vs @e1jƪ(>9=7e]!X)U^pn32Oc^ [vhTVmkrʖR25DVԥܨ~rv:%p00dƉx6 uhyBуP8P 7}mYonon]yAq]DDq--VׇGclK|>`=$-ף[MqK$ƋSa*&yE&S0 chmO4%wώp nvG0A/Tpߓ2Uy0U/k)Q5R c6B6^yit-CM#E)U!LOFT/x.51Jk]ePԷ.v^Po")mVi DIE鱥PRTR|o>scgSmB%DzAIՠޭv2=lђ38L,I]2z tfS~l&R7㽉 GHtݼx$w89|<;= qmfݮv8"=&UWާnd2F5$/ (D ($2Lqx[nE!U!R%#ТrbZmCUH ]lNf#1j_)DOml+:H\[An:nVژ)UI\PK Vj0͢pusqxxp/RD4DzxP{ )3>K`ԎƆtqH.xV"j/sɡVzhGp# OZ(/Bend[˸)J#lM Rkń,*:w @(|O'FB]5Z#f(}2<2B,zқ YA章ǚc&[ER~{L&l.@o<Ul5H)q?8;Z.Sz^\?vweCZ_|OQ,tA0p㳇`Ym./n/np׃ ipcj;9f26@5".ۚ;K{ni۶׶of~2xorgk{-85(XWҠBP.n}ԶkrUoۦ"Ƨgo{:h}YV;Xtrw>bE=c:BaK7B٨jek5@oO=y囓Ó{O>zcGyѣwH 'x̉Fjh RG)-q6ɒQFŨ# #0I O0 jWe@QrELZC'&,=-R!lGm߆vϭZ..tM|Rܶu]gG^zV{[/Llz3#1DRa'ҭIuz>}'6΂3sBYg(dΣfyX\>zxϖ#QXksSq&OV^Y3#f ;jT9`]IgZt񆔄{+c  floQf +i! R S밠c4{:7ȰցF n纍ojDqE,Z Ml2L6⋣??:||yn12s_QWu)k&LŻ׫ վ5= ˗o\|BI߇2 2a[(KIDATB(xtI׻2.(|G//oPF[&WYx~Pa#@cwWώOϞ=ݤro;Ұ4:YV' ñ(#YԓSXcQÝHw#WZF[1HeUD1G23뢌 vfu}aT(!!-Ҷ-kTYx>8O!:mrSLjy'>?-u12Zfa;n{ٖnX]_]^60p~u{)ӑ-='z/> +.#׌aJYr& Y. ?rQh: s3ޗbտkEY^˓K'c"}ˡoڡ8﷨Ђ1q4Um[&2rdq؏ U}忔'uWhDܺq%DR)aʂdB3JYgwv}m]ScMAFȘg.d^䠉}c͆6ZLs.XK2;=XmN/ǯn VFh=vڶ Xdu^Sq%+!S OSսiwuuc&(T# OG;?~zg}Etr\[g֧i.z^Dn Lyb0{@"z28@EI!!x)aqZٽ>ƣ'/\MgM$??[_\w||"fK7L Lz˓J<:Hw^Ѳ,T*ȠaP!STJdvz飣.b!ݏ)Wo| Yu~nnۮ秇 D2B'~w\\}DV]5,jj'd>?ΦM+z{L{ d"fNF=;͸)>$j/yq%t6b%'X6ĮE.jɵCej4l4+:JϴҲ6 xYW@|C*QE^L? [fV-~}toꫫu}p,GuG^ջS%*۴<*l-pH㈚ mlHBFqC̃=Fz*| uSAK^VօG^:dDdC)t^tX)qە.oqOuh:|`i *n /_o^a0~2PQLҗxۑڷJzL )Rj3' DJN,cicY`~+{p=qx#oS{GӰWA /_ᕋt, P ȴdI!("ULlD 83 b88C7Z@']1GF\uL:^;2⯒CDQ b} B$:"F&b$dh LiA(UUTTPʺjjk~˵'@ ~o9zcOe^/ɴykMLCPBasoMa~炼1gnP%F}4 SdqJE1}'o;7:c#2]5te̻j^zF'YCFD/N=Zy#a 1)X/fo8 s4b0& EB5ϼ ?8zc#2[7LR0X0ͰPӃB? ``PHƐ2>CJAiP5 nP+}p]߯뱎!/׾⍀yyuBt;z 8PLzqy0qvzkdyKD@D D0)Ƹwzo\z/}ޱ볎=ٗ~59D9ؗgp:v>X{ٯF+H Ѹ>E-,|h)ќ3>V_7!%g ucw Fݾj8} _//fٗ5w\0=WkѐW)t~'=NGB$qi+>NtLF5-DvI< ΤgQ EhA5@C UW(1m0sL˂PH^7DGo#~+u\\ovWo}A/8( 0{X8ttGy?>zLqcgK8r(py^ŜDzYoGFԊ"6gw\B2J5V9@qXD>o}cO%^/{pO+UQS{I1#8 *63xpk$&ul ]kÜwr!weB5=s  'q/]&&TuG"7b@l(y]c~ou ||w^to ]#ٙej k UFhjU24 nl~ă dM,E3ȸRy rP(!09~y)9,3q@zyo?{G.aؓ=||C⮸Ř_ |qEbnR۹p ]Rx6aq<ÜH ~Zy3p5@5& #R+҆PjiPbgcO]/O#~smpI7xT K:q1'2@^0 0t:8,άiQ {qkpd8+fq汔OGܙ11D|f$e` Z-k޿c#{ '3q%^ l,܌͓7cA;WR܎(NHȸ &R8sӓ;-gujMh[s>O7Eq$w,P# 3Gp|x3 4! y-SqZ_HFyS=8{W8y+>y { 4sKul<7݆&gG&@aiGLdPPw+'\YDO}8hCE2](4jn<3xQߋg{?n>Ӣ33ibmt":s;:2X G{F^3 zp[lĴGкMJҕ`{}L6O* =e'ĪVE(f3y/MkwaW}\ױ=C_~KE郢uؠɋB^7l~p,t39EjC%,o_ W˘N/㾋AN$ )t7Nwb7E*҅Ahw2B:rnխ6ُW|~w}+_(VO,@Te>E*Oh7gYV`<& 3( xQ828u2 1bjoƒcw{ 8ŠIͳ7ԩ[qrXt`""WN|et=()L̜dOᦦ܌5KR.[|_|[;қ9c#{7쫞W'o9yԵ8BB 6Ġ X/&700.KuK),!}*k`;g{2jTylCv$z X#d CAZg#gH/n"[XERT.Qذf_ ,JA)+%b0W_#o}WQ߯e٣d߹x7~ZU0j)LuyѠM,-eU*;_ɛoIbO]n%ZF]OWcE+8xU{47d h)Ŵ)1-Mznra܇k.tkXZ;ͳg0X\*#o\93-o4(OyzOlQ߻n٣`ȏ BD,~nR09:vv[XÉ͓XZZE;@$W&^WB^A" {S A 0R>F QN ŝٍ*Dj]A,Dh1 I"#D-e"/ͷޅ6Ik3i$7cqP.[XZBqL#Cob)0]՘Y zaBF8ĨtA1Aq*!w7Bl+ED96ĔTFP<['0`2<F$ >Q'cyܟ޷KG}uldz{2^LY<"%lJ'5M)c$i,":٭!N( Ao !!k`@_rȞBrLG5FW$Q%0ot!#z3TT Is]*ۼ̳@vYCME6)OUM,[\D$8SNʴ";p`gGxc#{[m/|s wmD9Q%HT .褷HZB%i4ɐD2A$#Ē70T > 46IcsA Fո zT !($e̅g}d~bC  i7hZ'^o"zЊc!]JoJΐh2 jtIa%O:GYcs@!#k5Ckezg>m?ԇaZ?o={i)kHqbHǐg>ecp5& kg58M$]2blvS075v1M-..T- A7b}m b3H.5sF!F6&p(ٰ/5HdH.pwCdYA~ߟfP22#L+Ыฌw)$p.޷;6~_ɞ{ϓ1ی6c qU뫆D7Rr+%CAҨGGiUR7%QkJtz{W Մv*<ὡ|C^G ulda[Y/x~Q0 |m1' =cfHn&[QopHbh(q+ MS]Wa}(\WxCsV8BU)He'6o( 4x/2pޮГ[5 Uu +")kUMF.F.ψopH*Xt`0\JZgD tr rX`<O"ͭ8&Ch=Lȓh?d ωF}(5@ _EwcN6ߪZj9cCP{>}M~֔(`!DYD uS5fjVLOcX`;ˈ[ӍC2gH.a|q< ,9 _G=uɾ?o{p tw86sRyz DEQ[#QJ& փI(|lC>ɝA ɩnj4&Py(v51Ƈ̃5N#1@Imv]+QnJ7eH&ԨMC8JMdX!y(#>}?M$-Tp M!|aG5# 88!2"BἌ h!tk!kE2(41!\$$9챆XUCD$¯Z5oU$RfJǼ(5Ejxt-/2x<4y`vaptR@7 {MdYp2D'DsL>Hʉ2D 2 K %Y,wMМKQ~2,uo'n&zTV CFĠj:y8{}A$oʡoGg/Ѿ^=/<#/qn#8'1 |hZ~C D(*Iȓ=BY8νޡC}KH{}Ig+m )qHF/C7{Yn .5(tg$_RB>O ː# #dɤ.lCDfkL1HeIPhO^ 'Cl]ގS3΋7,j3`~6бuy^! 8w߬>lM{~OF6~^yጽC0ᐺ `.T6 ^dd[$bE^lCW 5ȁ-##\;3x`>GR -J˫HKP:C]4CFQңvUh?xymG$UUë[311!pwE"#6k,1,0G>x<QMS;jg{j% ըD;.hvձ9_3LS8rhs 0 0Aʽ.Qr&jc750̅gEh)~G{]hP06i^$tz4[ z2.:`1)dk^B=,\x/&[,Dd=1Kpg3aawR nCQ [܄ʺhCf:Bjb^.| M96 &\p{Ww09C7Pݬ,"@&}|u'O w܅4wE{p)d2I9OkhRpv\8?=e _9ͳo @x5= l)ꬿ';jpjהBɽ!P%5/s. L nJOMq=Y_Į"2V$ːzoN$**;7q0 7 I=B ! vcY $.VNl`udQc !V rgVVF*SMܐy֠>T.LDo^d˿|wmNpvZ2?N|$:92scC6%,>T~ jD9ƇfNZX;8>| e G)02(؂hvrDFդPtV\CuQ9F]]֕qW: `gɲ6On ;\;N>IQ-p؆V4XPs(>'w#羬<ه'`g'w6x؄Zyw7ݟdW}8c@ ^0:) kHZB7C32o4.}` x1ِ0e9F@A `9^GZUaMpaRU樔AHխ!ս;pX\?K|LƨjR/]L2Cֈ}#\Tg u>31Tlh$})ni!$2(R+6eQmŏ0xwjv{}tD@齋q;B B)'Ck`nHyo4s$q[Ex0^3v<)[ %:C`F5Ә2/ݭZ%*":3sdlɃgT %D"UH=@W[pseI!.td^1xbgjX8UӞ}VkSGCֱב0 U9"ڕckuPW!}wͷƻ7%md?oz&W1u]SX-Ay dZ~s


~n]kˌ60M$% @Rj+!mN545׌0c\k`n4-LؐA_(!(hrJBv2LBWo)7F05XcXeW2^sRHڗ<4jVlEu3O߾a"kڣwxČK2's1-)):z}W'SL{0MʮzphJdm'x5ք T톡19xKr=\"ha\M>6Gd>e0m͌CU{)ѭXj}hG] 4 3D4 ʡ}ͬZJP@y!x֤u{ުWv ?C~H~^'3,=w?OGb?~Oq1,2f0MNPdU4 N=y |5.1jR~pU7B6c$"dv9FG8ƣ`ǵWA)LDgt hjhr-DIc() [Ui101&ӫg>ܣY#{y^/Oic?l"jㇷ_O5mxISWYA_is.DoKiWm Mlv]LK vFh!"6ܲü.RN7C99m g{pBEc75| / d #fg`B]WבtRa67cT.23qD@kG5UxL5+ skr?06|L $2{BÜ h܇s>&sg` /"rV8fmfGWNCbo T35ދi ^FOYI?E ,|o-Pa|K\q3f)ByYkٶ0m1s^B44=l\jO$PcŵhU 4qRTSc'`?^@]T 9=1}=:~Ucy7dPO⃣1"Ͻ|`uНVܡLp<_{TcȾ 8gyanxx zT0M`."Cy{vp @#VfH7ʓTeZ1֖rBpFg،lm~a5;s W`f3"ce֨t2,Bk7D#b ULH }=DZ?4 6WO#JS,-n`p OFa^_KuS&p3F;D4 83x+7Qh.Wn%ZMP4g 5{+}8ȾO̘%}> 6 qllq&pZA&Rf˟Fjt.2oOVWE[Glo)ΓcIՎJ B`0WWsu-qZiIamy9f/|\nCKk(6hQ5Ԥ\׊ k PVuNb(8ؽg?GYASMf? ۟< '&Z[òZDqB?d((ZP2L߄(ZxoHﯣ sN\ǏZ#]zN^(>k'9sр- [AywtEJ%tM;ϟ\Fyv9bjϼ#l/(WY@w7Ɔ(@x>>)LS?!_cWLUuuh4ȬA)5dUMU*4TS!Q5oc`{ acFf&+8n3B}++`pNXN_8m/]9XCkSkY#+Ike!1ujv[^c^7G`{/?_~s.SͳiO')I0݀ n|D :i ?)gSO\Tfs$N;nk\tĠ lڨGJBʦG3r;oiF(֒d6ÒOeBn^~"z~,A2Ipg{I4࡜)yuvZ같LyLM7. iO:-FoKOcJ =l|bFu6k ԁAQ"rKɼ^|I1D^اp'oP RO?;ַE i M#)Hjpd\}-Y)v+D%@5ArNwiցj G`s"s8!l=rCM(|fAM1 J8ܑrDC^/]mZhfM0xIp U)_jIEy2݆o4%e5AYMɓ2" WF\5mj(r>&&čt>\p.I:*c l+s#jzn*huB}ШN\(Db49ןևk<#|`vCj4sd+5yA/& T7V~t8 c ۍ$(]tK^жno(ϕk̐,4gYhvHy@4.kAٽTreo aw1r ztE▚9D)%$! $g&q4"Rz4!1WX M+cȤ4)ʝFh2n=3PR&5Fj\{ǜ,D$B4!6sa T*ڏ+hʹ*E]E᣽+4=`4( 3|GӼ Ӧ"zKSa:C!2akכ'p,$vP>Tsy;LG*?._Č? @X肑ժ)AȬ$QDE&t&d`(# čChX7TsMf7x(#{v:Q^To #Qp.w^K׾ؽ=/?}f7 w0bCs 钌3ng&$W-ip' K."hQJ~ʿq %8sv`; WL&hT[>ch]Qׯ3&A:_D(jګ6 IAx!Yw@u%VU) .7k )n|2ATd,s Ѳn`Xj4rrizt-s:c & Ocځ+;pI;=O. axb^Ϭv6}r͈̉ľ Ыjp<3&vSnFmʁ OuxGQ˸kl<(3, Ii_. Z=SD@L3H/lP̝J~)DlhXMU茴5.(2PƫR]*v0N3L\:{#1.5S]7yg,t:V϶wk}dHC4;PT{Є qo1p= ^xKs Ufp;1< 5DfmjjHbAbE/@ }t;]?q2` uⅈgrդY{C'XBœxi*éQ9M7g:܌`b֛s0V۔h[ikxk2|އb<6Ϋ4Nzʳ| LSS5\E<[[T>=?;(rU;9;BmW~W7X8MHGDV4 kw:XHz"oPSdIE;}4hi&4$(Ld>,t/sz,($Mn*\g1Xtyʲ ȕNo8>2Mkfh$$qcgLIf"u2S.4^M`<1'z&DSQU IW>N'[H; CYUdh70VVw)p!@ӱ[ASM5=#|3fK8#Bȿ|^6abk=X\Y|m>b%\|ɷd<ՌPo1mnN!,8d$"A߷>yKc1R WT)JWC3 r<=ech]BFi,p(N;M'{tRqmsDwԍl% 1Q$({`Vz3kerfb)^]=no$=C^31X6?19F yx9k@"4R5hNk@&Yf#$uowWl읺Я'Vi 4F2a QDu'ktHhT + cFbk`$myi9GoԔ^83D~ &3u^Oj)SB]l0 Ghu*H7T f Bjꌶž>Û2A pJϺu;WuBE7{7&5Lžhl|CPMF1UbRlcgORf]v.='ҰʁPԋ7ohM އiѬ# J8֕6A4N!W/{#bd_;y5ROONrEMћrDF:1$,DDxQ+Ȋ!StztݽC`ս(##'w7v&f!R\SYN ` ghCM׹A-).ʁ\6t'4?x7ܐXCӾozUj߭܆לEQgRS)s'[)y0ỦG\H*90(|:#eҞ& 8o2Vsn ^; g^7Ҵ 3'|~EӍ0s?:.g2UrHa]֖tsSb0|wEmi&q;'- w9fZ IJO7B9? [۶js5imZg[9C3.c8ktMFCL'Cݴqswf>gO?9sϏ&Q'o8vz{r<.(Jz1 =,E\ Q?`vSՠs3JD)9A7^`d0S U=&hG Ib:qyAFF%[MC>?j:X q/K(4Lלp7X\j?R^0Zw̬ۆ+c楉'br'CbU# 1j d\y^ذM5 n g,ɠck^й]6d ͣE=Hb5DNUht*8]o\k0]cfy cX^Ztݲx2&Vg |d_;7n}?1z: ` 4 bi :5rDDD 3wIJK$,otY 4f' 1;ر}* ދyO:/sX;V<y3]:12"a>$N&sɼ̶Q w/r+ SlmXijHl9(QsWT5GN6H{JDj +0OY? QL@JRة0~q4~{M<&v@{`Χ8<.ipͬaqLd>bd_wij_{ëh:$ $it@"B D"H ,Ti&olQqDܳmET(hª7"Rk$rпVہ9aQN]"![24.O>笸L>x|=߶ύIO"4R;N ١T'gPC =ESHAH-Y!Dԡ̜f+hBB޲UCyi>v0`638CH']:5vT!#<م\8U>d><ױ00(yE>f7VO_y~Fon7;ȷ&5Ŷ>0$ϧ0-FtHe eTDD ;#%65ش+ u:z o7u;/f7=UcyyqC-*I|>'~H7o (y5d@])\tE dJ.lh%koڙ́:@nb8 u'`0"Jq"xKVQIziyxԬ@NG)F;2Cu!5kpq +1nCR/Pmv/ԢO1׋7-{3UիW2QP˜cBژɀΊ+-+zQ`Hzu\QH e۴TA PE՛N=sK"Ժ{o<awakb?cMsoЫz@fRC;GK4n*wa ȚJsӡuRH-T76"An6!:_K+Lƻ50iNjbH 5fC>e^fa FU|hOM!MRnGtȚS G G!3Kz," B](+`PLCYןzXghnޅ[{~s-.8ÇJ@ ik5 ,բ_]~gtrkӟ.liHX|E>ӂM k$42c4"5!w\ny,2mpJF=ɾ>]C63PbqiB]@7TJԨ#1cݓ "?z!Wsp>a/zP0ʢ5tK,P}P'XQXa_/^ zuZ ɬA [Jk+jC}d<#mDmr]m)RHMBT [ ZT~U+!< JA҉KtbF).!Ym-@Do4O_i=={0-RWd A5PLIFP\&ؘCͪr71jJ[Q_֯.cg֩3DKYvG//dⲇ=QSˊ F(U<:~R5} ?_=M* )5ڸqCyqƐ)M]?ӍVC# IbXT|Gm`<ʕЌ*1~b_0JCsIZxa> zRڮq4ۃ>=clIrJ6F$onJ iO.k6 8҆DZ%Pe0zn37 &ho GAQZK>IwbwzK5ci>{N]{&qU0lȔwNEn+F¸)1)k1Ʀ45#lh['p8q-v9uE5A5dvN`j^3w~ ǫ=,8y ƣ)|f%r2M. Vc6ߒ{+!6ǓgF - L\e!'ɔ .SȨVW=Aٞ\v#\j…Bdșc6\iPIOH{?hX:R[BhoqƋ%5P&Ozg~S[Gpq M6S3%:%<->:F֙Bҟi63 yn1^A=FNDoE 2H)hnA QP =~ יZ6p31:I)fpD*' C1vE;h=VN*LG#1jSBF՘xuָaTj%Th4A(jvh4L=xqxXdMCqvMSt3@fM]pxlO\j6&@X&x.l۟$NoqQY%PN\TZEd+zar0:UL۩CgX6'u!dJ!o2#ua$D $m%hP6ZԳd/oqd3<3bŨI_cmWv_-Rś6j f 3JTdjIưv'Q\tݚcGWwë^/-1v3پםَёS'X&WNr љAILb `4#2c4˜&E\bߋ `Caz*1mt=JR(Xd4O;f3f I]Ӭ+d ;`idKA&E"7l:hfF ^ Y45lNXRZ2Mz"J1vK IyNѾs=w_uOYLwmĵ4{١ #`$sP}(1' J3Sҟ=eaPVHajb)h Pj4U*_;I/-nCSɐ`5$OϳM`~5w E7jbW'C9٥uM=1;k'p]irX׋SL+Vl  ² ٰ=,ta8WL|ODm4 `i<0/K@J+8}ܤO\(ybA9b#}Z2A5,#ݸ!|21C7#o [JP,)e$G{*lS27>qwߧY,^u݌Ң<7 k4 )~L˺kJ _p)Mq`2`2afTc'| {W.8ĶsЋBv8sć8RQl7Qچw7> |߇߅!l5{G?nѭXkQJG-,P c`O-#%%æ7?U2%~}FdPUGcJJohЧ7# uPO8+zB`:њ]G]FE Ma,gA2D*U}#,&h֑jJCCCք SLJУQsD^~~67# :Q<6b% \H>ɐ~J 0PyCh ia$RCB|)o{7</RJ-uIjQU9'H)R[`uP$r,ᠿwfyR|3C1σ0ТWH{@WlJ*0qSjn , jaO'|̇ߍzK=t5pؽp,XVq`U% HVΪ[-xqeӠ.uFV" r:fviF4ib@`ÿ+˅6D2. 5H BH̊T-TQAkIds oWV')-D]@ Uf\"`H)yʔ&Ij91ܧN&7 +zCMt *>/*S/;C0贡G]N%Haܔ5pU4t+d$Щ2!k7Hl|!}ǛgKS/"$ȰR'Ʋb2`ߢ4tz ?d =9}ko?8@Zmn0Oo߆C:<n@[wZcZ`>j uT#d.53:Ѭ01IRǘKi{SFwr{e@T",,u2)M.6Luʼgzz!&%PH2`ČoMqvuc1Bztg"Fhǧ0vC+YY,7Hb}s?پ ~oup)~> ~ѻ^WkJ]g[mI;{,YUXbZj ,c`V4dȧ$wzvT6?n"P2,2]_d͜wd/;ij( 'F;]˟W * ͖(mM^{ޡ]/5=x2\ ^w| U T{`dܰtU{&t>2{ u |3^.LHbxp9Y1p⿜X ,5:/%ݥM Qd8HhCe&l7YH2oꛏ=`,;DKՎuQSmt<ˤ_z{ם>I"J!ü afN G!0rTԀCʠ򰓿wq3~3OSE9&CN&;؞{K8Zv ,+ )SD_5'~qyr]rli() 1Œ(l$I> ! o9Tm ըܙEx79 6CI?B35h˚UIcjIe,m25O"}>C\ԇtVZڔ'KsIğR=х>%$Qb(1Uв^LIU,7+vBZ _1!iXC@4vlrë؞RF]S!$h0&m+# jV!~= Xxx3D c̘܍ 5a"%u% X诫;ӏr-^8.\lH fqOᩳX8f2Q]Bpɐެ|前6Ozi% %YdbLHfOH\nhM9W|(,WІP ]iK2‡d(ʼn4ذNh}vpppJ㝠ݮb4a9M3.VQ-"D M7H0K}2ӓZ-*d{֗Q`vš.t_O_Ll܋ѕ{1yb;`NtMX\s1E LV^NE%:NއA-KXBB !pcZ>4;^B) e+ Ku,QհCNsARFae{fI0#A('2ϓL['0k4/4SaːC3HdX18vly H<*qDrg|կ_8 /7Ox*ě\ꢧ9ZzGae؂ UoZK[<S7okkZf]1Ff/ϒG${ 'G`x})KK)w` \+wx }쌷pOŕb3g>e,}ɭun>19K$)gvwug`h6{)&[B=b^/_"B3'oR<N54*Pπ6\ 5TL";C W]4E"KqjSF"s u;@d T/KJC ZLti$G ~ļZ4trw%JjF% Tg/r z07Emd/+~_ZM7ǒD򙊋fo~[ E4&M úVQk7+Qv%1vl5U[,:yIJ3%ʰmN}|s2[{rxgW7a}e`Y8z܍>֢Ӟ(7  ]."s\p[BC=l£d*UVZg4͠d\j=ֹJ]SCCXlM!\U%cO,^l e2lGR|Q 7*qˁ|,*Tظq%|YW%$P L&kfR I _`l v A J}wQ4#K?M x}"PjZJpS)1ݚ`kg;;;nL'Pu֊="ba>zԑo@A 7|qd>-VCXn$X)]Og[^F܍ϲ2DQ:Jg jvi[N Imuڝ]v|ROHɣ,JޜHy"-:IG_kBK'W#>%kaK ӍcL5rH"Ngb y.BB("r $lrs3(܈kԱnIY> \Sl#i րpE) t}~;_mS"D<84V4dc9ʑx`gg'vOakwۘΦ:9OB5XXulc9 ]CU&+꼉<[hy EW%Kt;:3;g0?>?- ,#Mc/n1yw6b^PŀHƅ*0~ƫ J 69nl)__MY#uQY~Usx& ؛uD z䚁ܘ"&>N ZVc{iH1*f&*;E\eGM8b&ÓRr)%Q@=_{ _L뽿_{߳?E{U8?ą {:,j{=q5`{wNlB#lkfʨ11tM*$o+ib֤U(!ɈɌE!wМ&rY=Zce;]h3nr{t4Jf u}4C0ەt0$W>)"O-XF$2\hTB1E!t% VnS\/ʬ ŐE2lF4CV b} {K f&pA L! #z[5g z؛R/ykȘ3e]j}{* Q'ٙm[\0wwsLg N: RY|'Rd*S&ty,;]l Ӗ;S!}I7¢hNޖi: V~U] 'qqqꨨTx@n'LgGP 1 r]6Yt$+8CP,m#+!!fa[ ^Ku wEmcd^WҡNf!ŨrDU(=&ctpk.c+`#;u敄_C116D)E]L%EZ5QQĬ4*~sK~EEdj׋[B(Jag$N^;hI\:w#4 Ǫ?hhxgM5F%< plɗPk(RH$]-# tTHKo\<4/+=_ W2 F(x]\T"020i/[hwh#^JL]J' s)OB*DQ1[(SCs1FQI 2f1-DE, @`z-p"~Ds<!>aZ uaC.;uGܹ7j[B4B Xq"3GZ*TU~mXEdntSOx&ԅ;}:nlE;2.^XUS "#Tg[ʻC`3ee9SYI( %-n9%]AFIjPi}Y"mP8s'Ey8g(.wG%RY1hF%P1Ip&{(]8ͫ ]p'Qdϸ%X;:5=r}ybCrӵWh^0G')6O mZ&`P/zȂ,^z?MZ_gLc\:n<~ K ͚ڎ. [vԦlȨ%jK%ˀT0 []S_10f8kĻœ%Ν|,8fh0S"V7 hq/9y7j:$|3zg_JR3R]z AO^5{f@6=Z%敩(m56kCJ)+${f-nHΠ=i),{3yv tj39s~5B,]L1ŭ ꭕb墘znEvuTDtmwdjE(kdkj;'xjچ yZ/L <\%q+QWQΞ?_1S17D-IDATNcQNN5,X=li)`6, *t!t C#:8U,뙤 >X y;&SAӃBFF)B"h 0\T=|@5䫡6e@kF-Kf.[JiiFxjp^,%H8R L޽ |{u\Iww<[)*R⡵ʹla6F]U 's>l'Yo0}k<XqA)rB֒' _sxݹN1LCwÙ1nk]W:7RbU^tc.QQgc>#F}}SȥR;)QiI]+c& rj)) U)d-A5ٷ,emDJq7@(dtibrdF6pŒ^o3DI۾~MrI3Eڢxs^)]yF)rv*v-% Y7o$~ L3N: q<WpHI3IIk 1&,e֔ Ss&7+)CRJI U9%9?ȼt !v لB$_kz{ña }?oLoUՄvZSRՅ ;7a8p<~U;'Т;&G{R+H]? 9/p5;1r#l}cXq20~,ܙm`O~G]C|f)k|,Ax<}86ؕMڒبAPҲ'!A;4dcM?[`|zIM0)gb RÎRC QOMmMF*K_kS: $&sMB&o ů5[Hc9d) O_Rx8Cy=,A" R:rlk]pӢYŚ˭1_Pǒ. 4[(C<ҫjqrqpuK1UPk|c0w\>8s5]l -cw\bXs\єGWb ^"5  k(z0Y!~S9#!]uID QDd&h!l"5FJu\GZŤ hܒ5` d^] ,1tI5k0k ~.W u;k>d/_~ٟZֈGYVlAؓ?aYCT,ek{Cnܚ|TaA*1إMS/% :*wRII>qbOZY?zjvmRPˆq9|p_9F@*köThc֖- yZll)Ա~z-ExS}/ Wr~H#I 5fDCkb&{fS,CXӢSkSJ "6Y!a)]GFb0 R?Uor;ug$}E*q^DQ (v.0Bue<^4'L[Beae hj2I J@1;J t0 6^kopׇzX ,q|VSQ),ʷ‰G)@nF`CQpwep[l -oEhXs-$xu0*LuTj5FkW%ƿ(PCrC/M S!YB.SwtEAduREO(BvS4"R!k?9M;Kt LIi`ϬO>vVkk:[_λ>pӇz؃/O5h{< E4g1 j+08A TH{p43~w`>N`v$Ljm0.\k ZcݯiRcvTBLQЮMQ z90;f6d$P IҬ,\TLIڬE*;^BnBH%d!W Q~ ~GBܧv>.=A_x'pGz؃ č^GJiiS  |=hT(^4YЃVb?QR ->UXQ}3ЮEu`%I&F89{#B+U #jWe5,ʖ0Vf:$iZyVJbK[؜.qwU%EBX~;`RGi>@t>Sj_!orCjK{hzd/{yI i54MR1oc0 :8%T6ȵɴ(կ<#K ]K͆NYʈa+Zge48Q@1"Y/- BYp[iA`G/H:B Ώ+ lbҨ1ǘDߠ ȶYB9QoIX)5 J::NlXBT|.l" i Z%yeÃ21& >znNMPY7Lla+N:( ӕ)n_x_#u;?˯@?sͥv(r ;uMo@m;HP@Wwfn ?ѕ=LBCBWݹ0~3Is=ʾ 0h՚ 3[yhщ[WiąvgM(Ǟؤf><0$oc۱@,C_TbDX30Tr`9Fu$S3f6w2If)' a]DVLmt7~ZI6P!kmj)![Ξ$MJ$ɒ89eG-$((Y^wLJ^93c֌FyY*`rot.P#ql{[(׋v( ]LQMO5[kA g~^8`Zj?ckS"IY8 !MH9ijӯSBSMw!FԳaw)9Rk݋Ӥ <ՄE=yKy |4G4K7!|Jp0b,_RpkR >QǕ0 ,AgnD8 Nra4Ϯj4Zd^sǵv%tA%KF(]zyN0AgvcDCz.$'nbe ;Sr gqWbX41ڐpM4D690ؘZlˤD(߂0h6^_=kѼ K* "Ss Ϥ|1 {'21=Z"{TRqhMn( ٟBjP6ƘdoY%N3yK_v#o~w|w3E,tD:e\'@# 1`{1[a/!ln0EZM#ulMA:!)/h1#tmbwRpq~V<]ҼsrqlpA d'5BQgV˹PlT . ib)o򰜻$3.lrHjROv# L^1 ]E?Gz})\IFw{'Z䤳)c{tby3`fmOhu 7KBx'[qw1Ff 4A@h)-ӈ y0DX8_wy`ecAMz7LdP DFf_6~Pe_3:R ~y_Ѥm(bsش̨~u7'Zԝ<>zK3u6Lb#Qe#kPCF [dc*q58 Ƌc%}u ^$|!(oȌ5n'OZרKz ޣ**[l dhD<5$jMVYِYK2dBb?u5t=*Ag?;~ou?2;u>䁦w} dR1Zr\bc:|yԎL`6LWݒwJˆ.flGۻ%ŔDz-|p|XTaO)QQS"at1Ņ6'BwЋx:Ea tj8*Bb1zLsj. k:u3v=/Q 2p&E씙0o^ljۋXA/1_xqzE 5Sk)ݒ[p{f;v42&{ZpqjQ3y-?Ӷp}K),]ړ9]Z44!BfU<6\H{]p20T%CgI%.dDD[~` AIѸ;VJ?Ϙ# 'þB~J}vzT{Λ o|9.mYvk,W N W8Zp:fwea{D'q58} )mӱAizK=zƮ"Eax1Ȗ`Sv|Y.M#dIi7G1V=/ޘ`*.I7.tٳgl0'Ĵh ^,F:R_QV seyЃټ%qQ =9T2=z@D('0i1Ψ *F[ OV#hG&;!+Ãlڝ~>bn}s# w_BxA$̀V]ktpo~.%pqU!1{ghLǘL'(R"XLbu՚Ւ}稵ߋ \^[ 8"MxlPT( aIutavmaaH@x-z,GݘvryWMg8K!c)eWɀ̰4JJeVAH"xa3ᅎg'hIxu7{f/ [~_)j-n)؛_\z.\ˇ{8^-L3V2rW&[S2fjNSm;=%xl4:dl`ޯ`473:MD-ɺ=δ( ;S\\t{:֢A:r ShL $-Jn 'aI5cF l4^η$͠j,yDk_65_jחI.k[~w,v.ݗǕt4h`JxY68-y)b@Zcud&. ٚuܝw¹- ' Rr}G,J=pkXq|8[{s .z"LTP={bʌL#hq<bbAг\|rk8L{wjn}?K* ?~:}׺[a٭x .I{LÔV@oę14#LFSLGk&O5j`ڮt,I,t僴[o8lxG)ezD&u[x%,\DZ33M=>۾~r]_RAmom]~Mă>-d!ʲEn "e{ɞ(j 0d9KDȾvE߉AҿH#ALb{:ƅ81;mmB^|. !xfyk-FBZln%ʹ*㦦㶼 [wyhtQIVyI&,d^i}x?zk£ r]_25Ywo7-9VvM}DBї,1k&U# XE6wN`LhжXSFbq@'Y_DiS,/ʵY҈*`6aRZbF\ĝ#,Ko Qgf[;"j2Ka2j0j6 =F,sffgwHjG®#E p!hQ GR PH**BӀR\W$q8ĩvcw'Yݙ9g9~sUQQyծ{s}{#gTO& î ޾= vob3-7O;--wӍKw/`qq yU CF6U[NA7Mh{yoE}S,)&,:*HBveʹty+Y͵)Y$,MJۢ7;=,`.]JOgבC&T:@,Q< 6E `~-br5 0XIDˊL`"A=Q\ L l4]ESE#3!CIHqVQPyYt oP}}c cVM) M[hFmND8rOģ&y}76vkQG8 )v@&tdIu%|,MRȲLc֢<ڝ~2S,K.{sysN7bg=k>?Yk+q'"eVgÔlЍ"Y!Q,E-Bucף)li*~$R'oϱI^ͨ *|37֭ڔwTL9w1;VEuS 0,gׅVh<*Á]d؝uL(2gjkYbǢ\28I͊1Z\]8Q6B-QEbnTu!Pk!IM)RdY&$.վ /uv[`?ÔC]FZlr֩"G0DL'ĩjq-\0s+; *ѵ>jGJ'raplu5P9t>(fv@,*{(ȴju $.g14)her,J 2tЉTqLH3. g:U4~ɰ)t$;d7Џ27'ӡG<v]vb]\D~ߩ>GifE̶0 \G$[Hq%dRܥPt\2X5Žu:<^t{ب㬰UmW%rx4,DA I(ù$I:vx 3P)`XEK_~ ZE"/)«'r+.lQйFy0ӎV-Tug-vsSʍvV- c w jgL:%{s:-b].ѓTH jk8ODZujEcGyK-ؚW!D'YXb,f류- ah9bH]dK !Ϩ$oISJI}.i_ $MM$t eu$SNw C:+)REFY*Sa.n47-=caqRD i`I`xW[x`;npiiڲ-rιXdlb8_EO2[Oui"YNy~K(rljԨD2ίR ?\WqsYW"RF.}t-I"Roŷg{AK5t޿cg,dl'cqup :,8J^-L(*2! ZHYL)tӾ/.)Tm~?>RIȀcp٬WioYˆY1Q8Сa:';7B4 DzV\%zI~?Qj[~Ÿgϝ>3^S.zD/HU"7l s@ 0uW5*3|uhHm\~}K1^]Yg5;'q*[y_V2Uzwv?hJvz$a(:#ʘY & EO~K\/Vf6'䒖+\0R?_?~tzs4ugu"d!bBǺn{k0MC+j3q4 kX B Pd>eLuFjh >3 FJ[Dnّz;aQRxqj7YB/v*n$Ʌ+OPN&ac3>'铫ń^VoL楈"U)B+cS2eNT{ Jj|qVk\ V^[ڭuKG-[լj#l4+[.ZZ ] ~ښ1` 7sj3f܈T!3&o3Ea.(>28ǭ&/J9c3Jfop u.h89Yg6E5hkw{ qS?Lw/S i귋^ZƘ9`3S3tjdl~%/P}#BY4ԋk_VLDJ:;ovf}dzK$½@#uuMƸd0'wML{BNkgtȻI5)Dǚ}])`u0]beS{X A٧a kmuI=T۟|IZmL$oܱsZ8 M3,"->D&0O!' Oug:"7,x] hׅgFMUh43g2/fƍkgGu4)6EX٢4b>ri}KƖtnɉ=VR3*p䛸^5 {c6}F Ejn&.\BfYcZ${[dz÷ވp`G3D`oobOTkjߍ>:+#Jbw 82 ,R}Ó~[3ĬӦaNcXqOfB 8[Ŕ"~0xx===m O;BsQUQTIRb!YtSBUNUxo8px&eXO|`S-_!OY \uBR26ᄆZ߲n}zNLDzFËNZKe))ti_|4-4\o {ynb=Pt7W5F* -#};箮Nonʲ>;y&J @L&}׷C2RH3e]FB5k-lx(4 F녒,G`)gv%q` >BN8@GeTGS?PW0, bdR ,q;o]F&]9W#%LFȞ|oV߻3?,r2W/QK؇T$nHy,M=;s.E S-uH!`]R, S۞+!˯?ivoxT~>uYO뢬`7B ٲ/!  KU`1q&1 tS烽 a/ r"v&VkۮYvy RӘ Q H {O 1pLRVC`t@ Cڜ"rEdL'<xs||wl6&]{pp=[,| 4}·˛Kѧ:b~;jLc4%5Ň㮳KVTq{ь'輷}^s%5l{9s2%ku9|ݣUqۢ4UU刈#`#J\(I gl2M'Sc 43> I(u &hTZOdzlw\Y;^-/9g=PSș"T\ Ϧ@^ |'ft1:H)8^.1)q4#1'g} X ;;~|ApI"RU\թoH~}+ωYJxSRIY#ؽ s$ګvY)Y6&"٣z4!!#xLIB<2F뻦q}ήbD⑱!K5,H׳V$fiMUUYLc4dRSPpd ,C$83?888/._olb/cDїm:!j A": ) Ie:<^%шN(`&%r0%Ji<G !ӳ㣃l~i]mVz\5MC3gVi$(bTF\mWB<Q \"+ǁ\% p |2OʲdP8"E],om낳;6lٳf;{7Lp^䜈Lsi \h7zUUYVU=+)E %CHhedvS מx3)GƮgNwȋmcID8o.$5pD&x&6)\4 #1CgBw޺pחvs萇$JiSݽΨWN3B1$N% 3\hy\tm;.)QN rF_E<68|8o7ʬ ]*Y.xK\ !BOyS ^p~xx 8>y./.ʲ(QYou"ߦw)W:XQl\Ԛ)s" ̕[\dA Mp&GЧ_wn*SH(S xS Wgw~um۬ۃd0I)2p-"vG}/./`)&X%#f&pt*Pq#puNtJ&pwQC} #ѽc \u몯-\6 9N xw9`WSbH/`|Yź|DZj4Ot)8 dBXCE+C 7U7GF`'sOhɸ֐KG2c&LC'|ݽjSz6PRLGtdJ*y%&4-D@%c܋ GqR0bG$4$ S4CUjA_;EUч༷,14QBĘ`:\rSjTA"D7J% -2 J!=Hmײ۾{h_B!2Mt J p{W#-E8`goa2@P0R."o3Ԉ9։rMY̌HI &.Q jƅ(DnG? Ͳv;slzq ϔJ6_0G8U6!xLWdJJ#p ͂ TJu!7n F(FU>1]NH$o(‰вŸks$T69Ssj CϦ*wǣijf q*o%kh o;{w$VJ}8lryN.S&[ fLE 1U !jC(n Fo-Cbz)n.[F._/}w6k睏ŹKAbw*KiF 7ٖ2r}yvٓRZK.!)3N#0m:Mp=r,h%g{xibx@9:=19(zT׵Vڻ`K.%хa\ޞ+XHetXRZMs0:MwЄ0%\Od%'hg*-Y{Iu2%+BHB0xW6;ll&d/8D)`@ti[F4K$IUT m׏tz~}?Ou5Y1>MUn,V7Wu7rQVY&m֍!"mc)%՜<`lW:'Ny\PL*!&(uC.tt1M&s{Bb*(1)ꠥTFDV !:b;`SsYc ls}2b0.%Vnm1p!40=x\ mȩi0ZWY=()RlifؤPײ),dlZ#7ݺkWkC7苿{wDr"ll2,ztR9H\k2Gok:p+} -@ iYV>| fcXP7vcl>U䠜bL L a"51bAQYRJk];)~I>[$< prfˌT)F"UP(NS+ X0khe65CoĠ' ô͒b Ƈ4IuU*4ںolnznW!z"n `ouדS 44#T A΢(L)2B-8|l:Uк(nۍA.#'WzxUT,KC>GwMR'޻lDX.Wt4m(QH;҂b^MyIIe"vcdNR8 +ndiІX8T̒yeIG&!VkHCePj;Lt? Lɾslggw~4.Pax.Ex<6GA}; !ō {Zuʚ8D20 2ߤhF cWIm~{wc=1B*zyR=E F"/7 u]LAr&ISjcuf2β\Yp2Dp+d]AD.ʬBZNgȼ$B@2 Oo!(A:u<裟ܞ\G2u;`j\ԌћpXWMhN$ ~+%S q%kwSg'j0C9VJˊq#.Xd6Y)D677٬nCߢV$OX^`a{LFBF|)f"4pʂq!gwi+Rd&" "X*,gB[JI+Ôx+d`b{!B$68m63+m#p4uUdwO},^A@0Bqe*uM';)&''ݣ7gOO΃Rd.n[CZ3Pjqx:VK%SBt,55p,| _P+!ZDLrౄXrhR%tCB |2@Ur #R[X?iZjğ BkPx#r72ƑF.+ǔDCseQx;IrPf(s:ŕh61Bx3(G;׻`+J)8T EdH)M"C㼳R[ }5=o<<8_%vw)lPq JxHPزS4@y=F7N %X.}%6y/yR ">:|䖷V+&h`ѹXLnd@b鲷Œ65 V(Dxݖܘ郠mɕ4 <H>"4Cu%R`ku,B}u)m Cq#[_]O9U`UrZ~I|pFq7z\υ(!FY )q;or?iGğg!rν|ѣ/ooos rusqy4+RYEQHAJTkfr/Hx:c|*Kt17|(J۵y$X+]KB42f ?پgyҏN{GfeQlLIRը}4MCYjDyPFM W_}yss3dGgm~ݬry}As$\4 a;pY?w}/7m`zOcVWXPgc]m-ըaI_PZ:7zaHix e}8]>e,q!tkfqY/8X {%u)rz?4ҙ8bZš hۖ ^#5XlG'dn2{/bXJQ'2R4t0z` nDcA^7ڿxhCU˫x|3GK3EYԣfxqQR$vmߗٓ/C=+UBf8F,8K%H8% 뭳fXo1EQ$.m/fpG63 G!_{ v yX\(JK9 !#4xsAёzfH>XfLƆQ֮f`IISae }Ҷ|ihq abo2yS]=z d?V=!@7 ѓX˙a. S"@>֫3uF6O~{.xo`ooo>VhYGзrّE nӮ۾RT÷}bs̾ECm?j:ې-P.Ξ! EEt>,&h|: TC8v2q. AӶ066— j$xmb^ջC.C$]H }I%TYXR;)7zwvv'8)1:heF#gb%6?zgW䞽NO_H!ooX 2ؗ1( *D<ݷ&t85z@CJ=3QT:Q kȅt6xBfTD\L&&фhF2m-f%T, #ϳ65 0q ;Ex"q $Ȗ4 9BG>#RsƔQF?||,^%Ezћ=!E-xjUf5X78R[*W㙮~RLx$eRhLӳPbaoQ]LƓdzh{.82.ʳ݇hONncyZK0)@IM[STĘ˔eY\y g I|;Ab2r/Q#G(?K((5TЧ>8$U$8hG5 :-NXFCeC];-O #K#`ReRQ]N7S3{ЦW|fpٻ*vk{ܙ̱^Nm=#--qX1 m;=wLh2AM.V_+B7E%8eW -@`T|hF%DpziR~Ym _'O:× (*yz/)M-FXُC$0vȋH`tI "=Y(I&"t6Q]H޲`-/!;gy':Qp~GG in޺ɗq^XdQÚf.${ o F8yu)ϳX;YNg.>Z߱*uq>xV6xnv08T+8 gyt`ݸZ^VՔ|&/P$CI$0 9pCw?_!`G A؞H|ΰ9dqF9`D\ȍq*$Dꏖ UX_<yGVER9cvMZ7B$λ>&vD|C~wg£}ߜ?{qzW#.: I9MKP3Ic&b6YH%3$v2y>#elKmﻛ)=BđW^L \|+(@eɊ"304o"xN^e]Dĭ4p"T؁'/mU.˪a<"4vm .Ov:'l]ۤxTcQ+}ytZPUro) {#2ϪHbR,locoУdQ&ÊUuiJg-*0]8X\V }\@tC8-&JY" <ܞJlK:|.Kz:w^TI2BIݰ%B4Q>c<^MiehL` {훇Lr):Q%aGNe_! * ,y6}/Si 6 Y:Y3Rizg[Qd _o;&T?1Znr˱{X\%TIp=XYfG*]q4`L&ًËLRʾo7qVU0Xώ=/ş{xa9 L^B#X_M)al1,)OV|}aUtJz]d8ɄI8xƈ8G-[&2Jj%2;ExRI2P9K%;^)G̼Kkc߰ѤKuEa\ĽL|L3!qIN8I_|ʢtBB%=>[UR:H'$CdR S, UYSbQ1wmeC9*Qbֆ >. PZZ01.X)p_ FA~c8% 'QX*SDKr|z̞|1QJTDST>Ÿ>vvtƶ% iDR/VC/ G>55FJ2Ʊ|d"E9OU:!o>6 ٵMt>sέ֫fclQC[ gD 5v7ףjK8 XvEŇI)O HrU՘Rm^ s9cC| ޖl/ȹ>Z&,YT(YAbL|Wg~s)e{|;MYcަuc/޻/g4>Qzqs4Ϸbas[6Z<~6yr)&%D|[Ր\[48F,匌y*,ۡÊ $ip\{{1/G}ہ#(J- b:f\|VF32H쁶~_Ψ3Ɩ.-dgWgok$ƽuW){Qa [as吲޶VR09$>ZKm @:C5:Lreb)5ǿ,Bv(_-}6~˓j2==L5m}Iqp,NXEm7ݽYn fE|0!'Dے iAB/bp(Z^*8|p]Hj:o#k{k5ڔfMRX׷WS-[*Y{۶w֪b7;GaL!7gX_ߐ 7G,h ]hҠsWuk`qƽw `(iʢZ>K If y):$B8;yr{o~HiÅ{ZY׵4?l*/Fr| ,xΦ93%g9b]wkB!Fe[/OP?6mt^rxpmli~PSd=qrNUYEWvy!u9tw ]6~#8yf5i(U|!*c!^+qoALɢ`Ɠ3e1IwFigA\㿺8O?'T>Ƌ{GRާk^xU#9 zEpp ||ygg?OgTBww?t1cmaJ.O.L(T97`p0+RTF~dgg{亐GhG磷|Uu\tEBS"um*( Gz"M MMǐlV: *E.XqzEҚf| 3zzxl` %)Fg+ GV:lYuRؘC$8PXb?ZۭB)TagIdGen_/Xكoǘqh)a\;{8fǞR@1"\-_G{/&ɓO}smeb2: HE9?5A*%7Jk3Mt8>'4AR1<팔"Ѳ6~s-'iVu=3{G[oyXo>_/Zoֶ: FPas8N s%Lhy&z !Xfc @F`+"AOv/5 H,h"_B+״Z,֭fm|WYC6.J2ʤ36(6<:<{z=ڷ0IɍiYWmCW=hL]+Sŗsvyc.wF5ZK3?enPD3@>#8ɱBhN~۵*4Cd޼< [7Ky9 f=9i.o/~WO2$/ 3;o8 {k]\zZȻbD@1 lHb)|*crp֠ 2HChL Cž!ζ!F ^ެz›xo;aLn@\|S:0u%z⻞6J,?!2?,g~~Dy4 jَ˭՚3ԻOsj;SXg'>~+)]%sJI-#y<{dƇM3 $lOX-/c{scuXuz{u][p=O|ꆵ p| )3o;l;o pLqu4([B|T) +*Gܘ]o^ ^GMk!!cOb<ʾ鋢~ƳcrMӵζm.L9FBqmEɹfqho:o|3py* j.*oNpP;9LSI.H ŒVcdޢmGC"s\v.x*H-@Gz1iY=NSVpeL 3xk3>1Lw F} fy[bhOYxkˑ~&.B|FaN&k?诿+QWzXomcЯ!H;+^ _L Y#{o=z9 {12v=hRvBie9>v\%Rz^OK3K\ } Çl`'&KRqWj# ?Gt@T(C &OܳawŠxbVcѼR*3Ng뇂XG߬b΄$ws{Qb?R1ՇwÛgnkջbt77~x'O>_oìT|$bޛ^M|)_ܨc)fFgˍme7w>y*(8*aãY^OȀ#1:47qm0D &ݳ|qOd]~}yqrj0;ϯo ľŭOpvr͟45Jڜ"d>Dn"3{^j"O2ύ6jL=c-tJ&EG 3 ub]Hyp&Ũyo7RF<< ["xLȔ /^Mӷ?h-7viMsñ s]w(ÍH)h1ЂMĜRH[I9OKA>$nREFlt75G@iV3iYtLYuq|؟w̿ݣ$ض6tyvz0?O ?[ %XXٞƖ`8E&r$0Xp[ES߃uԍ]L$@ͪ!]j%D9yi]afZ^`zZ˗͢Ko_s1T0L=M)XrXo6G jXcP}$Zb\1aLl.+HhgEPIbR[ y,JV`-E2|7u`o\U |lǯW7$Cmt{9Tee5MJmBh p-@BEE@*+;D(&f|??N_p'br^S^R2 )L4apҵvӀE[¤ṚJIfeˢPݨmuf]/F:͛Ot4Cq)Q _ݹvKhZ?^oޜ>>Nt aaIbFoa; 'ch  Œ5ԈsH;Zبm0P'U:/'4G0!LyrsbZ?i}kA^ _nzק_>n_ajkk,v^4/܊$P ܪ0&4BKx 1.GKwcu0V.6zs);=\ea::P"6틸wއYo*[|uіg~(Yyaaq>yZ權BQu8JjH<"LI* WDn۪!Vԧ(\a^_y9ѢyYU,<)},2/o~뿙t:97{/df,NPyrg!֞L*!RQ[-bz<Uޗc s]֤R/)}Ng7gv7_c}W./nwovs1%78:g/nK.E;tcXp/H+k5+ >ÆUC 0Mo$CVgL_) B| <ȶS:8E |Rq07F 2p]%^v}9m_Z;54T'ȟ-ZT1}( 5RΦ*-1c1i⤈l]i}7qI/W/ſz3?|wtx7i۪Xac?+n7_yxUӔ1[5=od -Pm}MX5NU)?Nv3% NNg&aubWIsºX(7a\ΉUSڲȔa*yc*,Џm<˽ ֭!]͓J.Vbb,s!CijVDt"c* •nCV9Gi:öiN!(^C ~ӟfc7qSڼZEuKR0) BzZE h[ݳ-lLI&ko-5{Ы-fVE.Z4GuLIWT:t"y[2AH?jƺjodIM*BT @}}Z-.W^7 ]5 RkΝNL835%̀?1U`)b~q(%!=߽cW+V EWL%Mr!0҂3- m( 1|phiݍsgS:VƘ<”)u4 ^% *_R{*^J7Ӕk?%'P`DrI)Y[Yۨ^Zsu> PxFX`tryju%pHm HJhir gmm, h._?}^c V^W5cVnVO6u:̪i5q}cdāfQGoEWSة◺:LJ9UоoJ]vUWV9Xc1z> rO{7lM g_7:7p}"zclm/H3G>S}? jxjHfzAL.=0c+6w~_y'Y}Lk-e;mwach6?7~oe7ُp||-\=OS;g={R$U.nQQ;`Js*&eZQdsG{;͔hSə/9־lEgXZe_~?{_{t\?{v>n PX2oAֺ<wAgW] +yJCi|<?4M2z[֌øl7fG}u^eb$~\gast0?g? |w|8e?sϿRj" vV?+1;0k 7cHH'FS]!PMB7/ucP[ !FTOHXryM){ӥ 7?}ftqY 1=Fg\iXdԤ- 'k& mz!@5WK`4B!9wO1b=8eGڦds bgqۋv}yOӴ)r"5ĻѹJ}mCbR"F2i`5H1rGq>n {IKFŖQ9rZYdnuI&{jUVLJ~7ǜYqVS;-?Z%Q;݃'klʤw)ꉍ ~pUR.8pQnsLhv(4*]&缉f𾨂iwI1Ƨn Xd^T=#RFƷ^͘5L)(p,Eu!mƻ9aJcjMR!TtT=xNTp (g2kk;Ibc],j 뚱,3#y ez+bZR9':wi^t1Pem7U9at77qA32p<<yQ:a38qq`zv0:8x>\*uv֘D & 8 6"n =&-R[/:[n7(Xj jͷ+'SŴ9RjcirV+QV[59><]q|L ܻЬ#;(V-UwU8l`,T f{e v;n2i~g7ŋ/^ dQƻvwv;^6m/ B p 靏s9èӐ9_|3y4|)\zeMN8&ꤕ8Q(AV*+ɚ4˪;mɞyUhXZNU0J`zôLkL<\AZ|:NGgydp.T!'$՟WF8lŸ ^{Hs~3qSJfĐ>UϞ?W7ιrZp;nؼyk OjrYkϲ^CBcNV݃}s)1X*L J9 bVvNDl ~aj&(dWf/VaBVfܸX8m=rqƱO9i:q mnoE3|;:7uZO4+gd, ibLzoIkk?B[1a9qw.%_^<{ YEs;8k5R.6Rra4nE\`qT!UArM=ڡ- 2tP X /L ƌv8Ww|"H{gV'}52\^z8-12uv CV~C>2EH822Ԣ38k# 3ĕ,Gu‘>SE790A$e5fr:J~P=8ŕv߸gWWENi 1p/_dL)|OZ/Vfq؄,18Vlb9%M s Jg=(b)h"MmmUcд(eŭ3 ۃh{aXPO+HPQ}yhs1'LN>Ķ+C'5q [[2 -We b Zk殶?:D+>I_e,J]DSSNg$v"Ң03WW(C4C!g޿i]pr0q~;!91]b018:zv;rmM8#u(hlsx hvJ3P)w@Gv |3h5 xB"fF_ 2 %̺f @MwtA@Z8Y kSV%ݩ{k0lǭjZGHsO^ӰZ QWŔ h;a+XNlA]tЮZ,u"LŨ$6L-F,z 2t6EAk̟E F+>HOUIiEI5AJP%vg(ĉh*NH0" QU~3\0e#Ap|tVHqAxOrU0/tKR\^orm_)q`tԋ<π"$ k@Wq)M IXA!YgMQ:LT2:UwHR-qgN+3-t)VG;GŪtXds%52Y7r69֚YynfSk}<,L\$$!"] !,,΁ ,iҦanEǩ]n'N ^]ΈaPj5Zjmdzv]u;mA f:P> 1S`v)AsY{iINt:òDK;[b%iԙۍ[ɮ*úDISq^/5b+#{HUՔW^yǡ&rCS$fDw~w(z5fLZcA.P1l Qʹ8]fZ9;TA:ZV*X9! @U^WC:u¹KS+ќ3]$_츣qn3nDp@ ,bjMj}||xxx՝!P!H!Tu$猉V0[/ruŏUӕogT3ۄeM v85(C hʭ+ٺ(]05J뽏1txV`R%S Y=aݵߑN1}h:R䛮%oGw-+.q,Y:%g]J95RYCRگA!(h6MI ݑ!̝{p>ώ! Z}kes)(ů<uw.1PT9Ro[&IL2ClZɘJ2s$phh+}m݁NYQnM6ވxn68<]e@Kr'\R.ޙ=d FN,HJtc1ͽ[])}/i 4FFnJO)`LTzHfwȆh/ J%rUpxHITzIJȯ“=QNIlz1圂@{5F=iY W'IX5FNadD~GlQ(ۈRV 5vb E~[ ,Ц›Jhn˰¸)Ųmιڅ'g5c,vR-F2 =]d^9wHeKMLt<%cWFPV>㇅IoAB}R zrÏ$V\Σgnwl5\bi\oDqkHWF}@} )쎹RE'YsQ08λg^]\l/݅Hd?B]*y)TqĪzM;PD""!<7! wG+Oa,(S1EƌYV]Fvgm-ZJ\&٬t<B)Tue^j@QǑ%k'Y'=xO ^@ZFH|ǟ*ekVLocYp rS((΅5"CK? 䎟cAI`URm[MZbt_fw7S)5rUr*PHUFF{ѠܴCzeIǥ\uC%҉[)=0ڈaFH{yduxmojgH/a|94tEM*+Nr~ AaDUΣ殽 &bD/Pb?~t!awWWWðA ,榪e tK},j8F; *j'(`^WLe/txo֜bk/ɺXךQүU3YҎ\WP&Ā0L l'*G@cRhKCv5B* ZƳhوu}kGQ$U#SB́Qhm{1-L<]3ܫ2NӬ&YiE)0n(iE[qrJ4MôLqbAL%1P%^]D'.M+|jKJav֊@wç_dҨaXIКmf_d!;É Ӓ{γj!L6@Da;m[ CAA.1ʴڒ/R|s\4Imm%cZ`s[]fVZuE}{`\D ݥ &=kTól ) u`ou5Y]To|\h5۳cNy6=Vpju bv G]п-F)9H>ki8y26"To6S:չi@ɡ=*.||GPAs p^ӧ߾q9-*z̴$2H>{nuh-СpfV˃YVt b[(_ sH@J JyKK{VDZ+\ru5n9M["/bUe׫oPQ,T aHtut]U8딮)%9,s2B_K~t+J50$qp<GSi i)~oCh"G/j :C<a~W`f%Y;ez1V~Z=|,ِ63cqC k@>RZbūFDY1Vec:SiTkΙbzT$|1g:ߒIM)&WU`Cx']ڠiѫI4i@XcZr$y0:5XDd18]JOC[svlS<?ÂR>6= U5oW1Ҁ *QjgM1@m5a棥:1"*OhoN~ 0.v %ZԮ0PQSvNkJwyYW) :?Ԣ5oS)6Qm`2 g\>lP2$Ͳ8ߑ[*=E6L_=I{eS77Wv)*qqKtࢶw)Yy]4M9áɖcdj޵ʑ\)Ⱥ%PcٌVXy&%'@ u {F畩'ʩh 72_6m$&sڌbƇ Lܕ" 9!ENJn3EPl݊j5.t*F4NcMS%(F:KTwX IFuSt8Ma)y~e%ҌOb@]4ּ{g+ :O't{ @zGTY;8?M-{!S牪䅉K ᚄ7:vK&RO%=Pgɱٖ6v8U=<&U,v{.ϓhWrtFbN*#W?%0faP9>>1/ͮqsxsqG0+NRϔkJAI1v)fo=t>4,m a![ߓ)'i4#YGiuHm 7=Ok[DOÿ Z]]$ |Q'y&Z5&TErhٿ Z:PVZ0eͭ|oHy4=1h/х֒5߬x5]K\"An*Zq Ъ*Zs R lQ A:knCvڶ.`>CdWZridkd?L7ԙq3bԢ3ŔiUl,IM0IF?0g3mGbp,0Ծ>9(BDs3Ku2 ]yw:tG#Un?G:Q=L,ugIΊ#=)[b0S;["ȍV0Q` sU:ómu+ {jjɎR+=nSJ0`l] n|pݗ H*{ 1Vb*\KO.8rI5S( Ւ轐kHYrư qFZ{-<4iLqdA>2ZDFlG 7v/uQ NpWdo;wn)-N 2!6:nvu 1*Ǥm56Ewoo)Aj:d \0H?l3fu[-f  LR6%ᄪuXC x`&8%ҥ\ɹ$Z[ۙ$JoY>exBelNmXXKroJ*S&/KYp0"[ҞXb$pf7ITZ q!j6 kbq#pl^_9cs(L'J55b50KܒY*}|' ‚{}Jj)1B"+^u;ppRޏLM9b̬''``pȢoT'6a|/UZaAwbFv [ѵWp(m~җX\l Ă9IF:|Y=dH]ůK( `BD㍠M|Y}TIJ$HPb1q+Vf1P nfA:wu7YF,QuݤZ* f\N{mQh@.Ss%D~+m@E" %5WQmϟ_{R~QFW˚]Y=U!Qzj2e&n"d!Jw+혚ҽ@8ukC!b ޵ AuD]vU~'L9)ݞXW)LXŹ2TQ䯻o6Z=*XKIM/;}̒.RnɼR8Aj7lJbսkho!jG<dKw5W03V*LV ac+݇D + y{KT9IgGL!,-q&i] lwCCǕ 7^B/8MW&;"<ŭ(ݎja{"?r (sG,|%,bFN5^ZWq]D0a6 [f# ҝr`IxNf>d9_.Tj0[%I+7=K!7ѵ+HayCq8,ܶWJDddL燦?Ī~WO-ewɊZ$#'l+L-ڻǜBP`uyZϪ*OIuaXAےŏѝ(yz$)XE@}}Tf? H!HgR|N*ȨUiQpò6Y0!sEzObyt2Dz=n+ )UQD!/XW?p L-9K!a-;e J'$URj\jeaL)?<<\0%Nxd#B`|` (]-HG=}RaHiX+D9xh1d)>wiOJo~Y|{џFd̖ס|2 ̲x=G|W_ 6`#m? 4w0R ~8~NsáȞIoѻ1E4Xm' hr e J̀츀CaD  AP :(e" zD^ߏƉh(9t"!d/ܝe~qGW~o~oYO|ۀ2޼._nh}eSJ#G_^X"9oo:tvuub7E #AlsCASH"Gt5)-CA1VJ6GQHA'{}~P)x \L,HTHHɑx=H /8M[BƑޣB@ *ory\ge&. ]@9:5rNϋ*:q"^s ń"aD?XJT0A6[}(DӮ<\~]D4CKuE N/x^oOv|/w=w'FJ"a^_^xͬHw<(R֤;\; =e{t<=RF"{q8X?8y7NNno_\.f N('`f$+,V׻N>;""O 9D޷ö?iPɓFBDyt<ThyLQbx^@N7׿$oiP!$Ptq=tm:I6urr^??|腱/x||{|~ϓⓦ=Moo4GR@q?P)S]64jsQ̷VJ!Rzny0pva+? jz/jssz~phy{kzºb$^$X"i4N+2SDE߭ӍHn ؿ;䔈Lge ͪܦU㽰S#\咽RcP)Y6&wCcM4k,paY*TA?+ҥ* N ^,[w}M~wy欻X`ݕ>md,GinE!\U~wg_L2R`` EO!dA7h0rů>_o(7Vyr1ѓ{P;;yаJ$^”x}zutɽ/.`Ǯ~ aڈ4블}0O,i푛,\l(4>皀F]0ӤGE2讶aa6?? P25z1ZcDXoBA12#Vk_k.CG5;*\ fb`CEs硰ޙ?wz7ð\^E 'd; ,vwh4U'['/>[o.yC ̼o)*aB>Q#H#E3A_?ǿ~9t32wˇN<|r|f.dMǩLMa*=n.Wѽ{+ކCעkاf(]q.UTbFMH fc^)2œsfˣmRq*J*h&(S 9PTc̶#;%?H_*z# kFz[6Vr^Xŏn鳋|ãUy,18 w*/`|h>Ŷ$c:8ʇ%fp5gԊPbѵIh]~cO~ Nf4Y4 v!僇'ou"1=b]:e$%eӳ؏}?IBnH--Ӭe2¼I $TZ{^q\U<,YDM¶THU6ar0=ϦCݹ2]^CЬDӤm{[xKkP2:g/eSR0ʐ;gy&9W zg@\F0&GB}ۏ-]ٮO^Wj#+y?j`rGHh Ie2u}[tIW)E o~-WIwߜtVBy0ru5tĤ\, =}417^* TW}z%]OWO'C+!gs4 CDi$x~7&N۰L(I|3l#czXKH%(iO? gϞVu% $% h |qsbr[n U13fl U`+pC^5[:zY5}J嗏7G7vb: /*€*Y#i'L<;l4q o`|طBFG"E"d섔 ]aW\s,Sa?` HAKe9uL9!~ȻISADΙĶ猌4˜]&ѩ~Lno}I4dμ)BH'g8tRP 3;a͏fn嫫.WD N]QUjep *50Y1+;`[%%VkWgzR'W0:J-a"R4?|ɽË*Wg1{׈"Y vKS::>םwfߑׯzM /Fz%:̩XH{#EssMJK1f5)?g| Se(eȽhdݩ*f>AGML^  KKfVM 'ypؑ =/^O7f57wuo@Yx3{4/ o3;ad\e !V0Q՗O(3**x21ܭ'i- OL5ߨjM\ty(uUkh8}K~=],O~onbΑKr>|L97{oMA?ǜըqPҊ@ pVA!qFr y(2s8zrWə#)hdyaҰ4V+Gֽ-i7tϜ(;gAgJ$IW7/>>5.>ƜWvj5(e4=J pFǓS iu0X<ܟ}Fz7R#t~Gk0Iapr>{~檀lߍ-@ J)h'T!.o]^i dCr1zr٪=ĩ!sT:brLWͻF*.N'` E(I_@<Ș vYC 1KNjC|&JwG<,lAϻ|y?|TNӬ>2@@t]_|=y2?yB)Vj.qL#3ܵ\u%_2n^!Jok]h#mp% mPvLv׷is8ܗb`eܸw/V]a`<~hLOkKv֊]20nv7g/|٪<q(>5] bu5E u\Pj&Lwӓ7钢V(k~qԯV٥\R/X_E;mTb1F:H(v<î[;Vƞh>Vxn:=M Tꕽh**PDkH=8ŗ29>fbq4^9x SƁY۲on٬^]ܖ{hZ 5{ӇQ{&+.(*rp{AL~vxrt~]c/{`advXP!foI{&܄tTH]u&ErΕH'~7wuR]iЙ qyx?PJ%K֭I(:`*6IQyBKj&ĥig`\.D2&#kE#"ПSH(ׂ"U)ԇ 8=E's5Ӑ+w(3SYIlMk6 yZd\m_q-.@2g&z;ߎnXRo_ۧ! fP~ݘSFX71HI\^C{q61WWc1\#Xs%Є-}(W44?9y{?˛!Doo›Y`9?&j5 V@b£"@2m.p˶[8qX`1ÔI4 s)nL)f@cN1ZX!s%yȓxzh}*$&D^]P7ى@Q)1V]r>-74oR>ݸ͖pk}#, Y/wႯ[wtmDa zAsހ)M˼UuvQ3G~´s߯%H%MK6aDpJ]ŜSɅ;Ů6Dpy7g}T1DM]BaYMsT)hmJA} g/fh&fi\Lb͗ڸ˹ 5g^5yw*ZJ<  >8D[s'ꓓ9T#cÖ-Z1T(EU}K['i#Hv@E$rtJ)A[۳{=y_|WPb5~{V<3k!a^ k[[W cKvb4ln \Q \@DRUEP2O.ɺjR`(AUZj&We&o;7M$MQcEi7Z\Df~B}"J (&ә;?7~Ãâs9`a fDJq3|"t2%`7欿+P[h]~-D3<&jym/?lW `6ܢyxF[90?j. d+qcf}7>ߚC' awsF 7 њel T2(ob-:?nwd ^xD;x4PS+L~NPhPhNMD.99Uʩt[J1lB_nҝQ*4cAs]?ڃGLyxr:`1ic]e?Y؄vva<җI~p/+tRo-Hld;sY]mΞ?,ff X5(c)ɩh }ɣˮXt5"$0d'늞^^Wcgln:,,yylM6Y54Hil&P$;ʼn=E#CVS"Yd[jJVqZeBV3uQ%3z4ҩ3Uκ&ƛHtgRVr<;4FDE﷋tvteML'4*^R# ֪%B1y/g'۾woߘ-QA7º$()t?pmڮn.πa,=+yYSsVCq" BIR|(d XJλSdbճ/ޚƅY>$jL9!9Μ<Ҥʹf dc$SV|{ - +YofBVPDL1U>C,[ʄ "ƇDJ%0qfVQiP# :YEwnUm3{ߘR/^>/eDN Aj._Jd*+4:<gc.7SGaWg3;Sن^̴ &K8)VIr攋HIJJi`/ܷMC3c Ԏ\&RA3@.E(SH%eTX. _wceyPsPCJ sAV1S"$({fD%3DY5imuzV*5m-Ϙ] `H\IV*U̜}W1y2n5BAWF0(I3AӔ}?Lɤl6؅EbE҃¢""YN؅s~H_ݺWqhG?]1r ,hTɏZZH~IR̈́->}JYO'3~g sR'Ѭ MgyxqPh9EjW]Ɵ*yT0Wro67欻]AnCc7iL{qґYQZWZJ 0&>ɀB,\TQcIV" AUYj%-PPJVo#UlLȺ u5MB0b)ht.BfW)CyS`,zsNK "_yۮMECMhE>8r*TݦMRXdҽa~1:땭ާ , 9(E%Geu&)f]/&4= 1tm8[ &e|,89gfPJC1nZvQ8`ѴKK=,1wuCT5+č[4v{ߤ^:NhSlfN7D1g"kQگ#WS3?Ұ #ՖJUejTB2"Wc]d84ru3)k0YyًQ ԕ oth&}!cy'5d3@O?l]Ğl[߁  hT .3Rdq| 85!3N29YYEFr"#^B1*zRv3S4y#}66@Rާq?Y۳PASccV-*׶qoT5q:ZrsW̲H%R{0M{T IxI"qG:mf |/X(yGwӧK69RJb Or_;RJ)vy}{Tr m.ͳ;UT*!㻊=LRhʤT5΁FZWXrwi+hi ;fx+`K`̲Uk*Fm`u^KUF qj@jрc5afH01+|pλ~'b={w>>MRpYġ/[/WPT6m̛k&7;=GlpѷQ'T"Ua}( >EKq+ַvw8f Vm = pտ`=M{;aԨ*;3buY5ڟM4)+(i1m#Qt̲,`Q_]Uf],OXuL#9,,s$;ltþ*46u(ZUz_fR uG.6rη>v@16csnp4ǭ:_VMߔܝ]JQո)(.&z@Lހah❴ b/$3XC:Y#~8\];5Ufi6WĶC*y̜Kl^*|-R]?ob#էH~UI; A 6QT *` &@gh& J,R*݀qbZ8z6[#fg;{;XΖm~g;TORLڥw??{&+@Ym0A| 7W_^|规1sƒ5mk_ ݂Y,X->Db:x%YİӞ6v !giڰk(VqZ~uPuaPXΫHp=xÛY))cl`BUH\X &H/#ֳ4' /$}:o"+RksR1V7D72C)Yord׻[?.蹚c l2xU6@ Aq._-&n^}^@2-+_}*#jsz+M8dq|rz|tzp8vKofeOAMY'y6LBl \jX&zm?1 3|l vϡAϖG-peu)'զ#uN,]Jփ6 Z24@6:HzPiSJwUx_d:SY0Κ,H= Xƒnd۽lT4dNPr3pI")`UQ0ȮVG\RΣ`ʜPt&ө0݅ï0YXƸXNO.}ڝ?%r˜ ,'滎wot7aT.Y< N#bv~= Y>ps#J&"aQ=bGX,x0nVQ3{FW 1F8F,iyw17a^z+Y)9G\l9YbSN,z4\l~P^\2ph Nn]ꌪ& U jahXC7W篺.{WGϻW7IDn/nk3wzT vs2vS{* =fw⢞R7g=hbt'5q\?w0?\FךmoʭpYFxi] 63 C_^T-mk .שj]TFHDA&f\u'[w^eEj$I|P$H@Wr6PlNRf 6**%X'd%Yۤ5|:lh3 oGpM(–K6)yw桂Ȱjr߀r9?M|8`f) *JIWfi&M} u̺X$NnlN%5#alSvIUl,Xz5#Amw 7}^jz~_[2T{y|Gbl{TM /xɌl幪Ysw i(X,?h!PwY*rNkVh6ejxn_}R?@놿-#3KRɃկ\vu觧JCPvf&^}oFHe TBW/^;Ujлc$?Z>(#$4:ՙ"9'.=}̺]!N)0k &=RGQ\,W1ݵq+Kwک,w,RCqh;RF=;c;׃>xjEZ˽[kvTV۸kCVd4F>*UeɪV`L_~vKN7 hXΏjD,u:PJiuust~́1rakۆ* j s*׫O>ޗ3vu XNaS$8i(nIIJ*N!5j] b3燽uV4WE¨O[&b?>Plk]&E 8rmuݸ5*ozi +`=L̽f],I`VVL@ݟV,qv*_^~Յnƀ!)ī?k{̣.y-r)):ylv 7z"pqiz|ծ7ZDD.3'UXF+Ndg^RYs8s[$-˟~4 ~c8 /N'_'őXY6`TSY\` º3Ur> C=}ʩ讽W;6*4V-vEuH(6Y_K^)g?ߐ̰\}v~tA;kyupӗ!_ BJ0$9YcHc>J4;d;-q:ҏv̲56!|f\_p?5]&ɬd[+h'XsKW+ncA}4xsS.TGv۳lg%x:SnL48acڿCf'Icn _˓&^=~[W,,b9]Fƚ+Ih5 Smyuyjq61vLC\=ɪhe֓ݳbȝVHْr:GN;1o_QfjpvsVf֟q[d 7M\.N6E^mL:~87_/<'߄vT#fkmtvbTQ{{&bz ZklC4T &OUQ.)J tb8O;C~ އSx\KY{GR5d:dSS( =^ "΁GܰWHM\رJ;@_q,JPb$Xu^nn?oW.vÔ4fd2< |)ť{kzm̄ގ\X`| u214@W'3Jq:?l UlT=^~=W+gxZ(a?МވnS]OJ: ׆:ʅ+ 24l?ȩQvc.\{?sodrvQ9_aϟzCw}Iyp.+ɚ"0$5x1)-A_sZuR}-p=kvR's)!# :u[p'Xmr+Er\&eXe-o˰~̽ M#y_n&2D;Y4 H#C~ٿb燼 WSoYvePsWuw5 IJdG8h)d;7^{/pv^8l,-Z YGAI ns2#펖ze߷}3n C~v?y>SKbV9Pe t::~1?s_7?8^tEi_BCzyۓQhu܌R`]9/-⹈j^_x`X2ĕC}_ ɊmthoMKz6ĔpuOn@t8?Y?*Nq7ɪ T 蛬4zac `Y&JWZ0ajxVaM+ `[\IJ+$*hۋg2w{̧9ob\զU .aSک^JY_?/{8YGg<<}?E~8\jK) G4alƓC_y{UtNPͱms\.\AY@  .ro_ΧTg{Vj=^\ѣӫOޣ赟ߤ^%ӿvDJ7nQ:lF4%)/tVi8C Vc/>ZjXBi'V }$ lkADĞ}%"%,roDϰ:,3չMUfՉ}O˧|2 ?}["<հ靛7/ =XmaP qx?W~[?-<쇷w?|p}zX,{u#)4zn%]N::s?.ZSܶy8Y͗S% @}Tԍԓ}Kͯ|+,"ژvH,x y\ y}]3pܦޤCzx?cݞ<煻UƭrZUjSJ t6tne`Ż+ P4,w ~aZI6WmWޭ揋<ԢXGn{j [`2SNJf7?&Ze9fڕv`ڬPĊ\n,GO|_me$`C#xeHRܗN0y黏6V6tSj Tu pn2w)\VY HD LZ#5rM)X0ڢ!ٱ1#$ A(jQs)%rmi>tdλ5;s{oo<ݰOZKj=Zl{׎6lqq C#0׿?_;Ը}{v'nqmgف!&~zr,5 VAKSq-o~מ]%Oy5ts[ r>soDj(u c([]{{6Qg*:>ao#]czk1DOxt$ȴ(F*B'#~=TJuE[5*\V\fx.+qX5R+W$.Y{enqKxI6yu֩,^xx8!M{H!U%|n}z6eW˯W?x۽ __Wqz"a0o|7?ʝڝ3u?~y%JVA"}RvE|3х@aqw9zrHq^|/ٖ]ij^ pG!0 Cw6KZ倦-G:ȑy8ZC:?XDdvoO*-Ў-q"ԙGx*^羯ZgV/b@uZG$A;,˻GI# #X/(10@B=UX%Ti7y>{v4Ƭ%7e)N^v^7^/q\>L-~koM݃XYD\%?7/?8~+8{hʋR+B4G'Su,`fDqo/㫏,t.OcE^ӡ>܃V UuR9L08G!ėgO^"IeVv,Vq)e3OO>e:}mPkdVCEUz4R!#l:ŀfz5jmJ$RL-FaayIYF2lKAr|P&h jnCWÝjs>EmEEWNߜwP=9~H{G;}9U?޷򡞽gbaX^I<$'^˚"HnXn4|<$nhKrUe36CHB-_k buЫ}0_'a.x3M)V"c^Hmϯ_=<3[9Ф QPݲHVH$N>j'W;w[/}9]>xiAc!螳Jt'h=` 5nE$!z9b-m5@|O|c3Xި@'S a^?0gs>_&>~I[ٟ\e:;lqXx 7'_տ=s^%2`3J/>Sq"P%w=ݥћޡ}4=s7).]@S//Ǣ ÃaxR[rsɬ0φ' ^}{3H6lV<'^c^kQ\n)t>ċ3psk/qdukO~p6XG!߻ۿ?~d{̯k't>8Ӷ/e^)X:(ziJ{Gp8"gnrl=OܐQ!Z^diAKX4\4PXD-]NrhW[GJj'5_Bgy{s3zt!}-__?=zt K Tqzo 2=lw2105x;wZ麰V ݵ0eamUX/0t6̩eK4$j;|tuIߙxN:) b1i猵pLGoyx;ճPdzrs}/~w~TZE:}`^r<,W2 ȯ26+RO<@C1d{Cc#$n h+2D#zx9S !⻡R-ʾC"8R\YXp@~Si_?`Ń}=w7󟥟4-~ э@;: =qė*#x`TjdV\=ڠM')Fir(TjX=B8Wҁ/x}@4{j_,>|&֗~w^c^rQOnRl|09 |z_aT2B,wR'.e9\爹@udJ) 2R|mFV" b}FP ѵ`P6wz`Gv/6qTuԚbIk;8 ?<=гh3Z'grrQ!ιPv0g1oVc@:a$|qkU GBƙtBvUu6kZ{.eSO;虔B7kHw҃SԊnvuҷW~wCLpݻ&t"ԹeDbV)(sNKѹke6Um7UKRaEIbkL '>偬 $%(w`õcq }U df^~8^6K-^*̮Ư|1]:VveWSKCKt$Q#Z^²xE !Ո2)(4W#PD"*rNnJwj E:{B4SBOӸH_t_w F1{㭻7x<5XKY KLчMkҸnNQxƔ@q)eQ3jo3R1>/:wgkh*%_YAC >s~C̲ۗۻjx ƀ.'ѧ͏?.i[wHi~$izSp}r\˄Q#ˎ qܜlnN$͒˗Au c1z>ڑ*BZL5Um*njJh1">mi_NӳezxOοؚ )H)Xi# \m4hЁSP6Lчc>'!n6( EM6\Wm ZBC(#KCE[p veR8ye7KF5e ^>Qi]3<5ٿ@{<$D`;`x .44%=Pʫq=+wfxp 4?dg5*?kq'/i}BCޚNޤGvr"K+k_~++VT[RfC&r+ ԝI 2sҘ`<xE/K':`eٰCdצּ葹WS+U\{\}-]W+ivY â=eOapJEF@2ҎrM!ߢ};t>/7:aꋖ)T:ѫO.n';ؒԃ6j T1]\'s:!6h+)e)hC*;>0Tʟ(RF C VfWŘ2α&W kٿ}T^9ELthԛ)>bԇPХ427!Jqq1@_ :4O%^0h Pwk]"+4Z3zXfC&ԲA_.|쭣>5BΞ]D7ڀ-딝zm}Ͼ2=yڔЭL#ܢ'7諑hk&k!s3h@ʑ1젔NѠ)4PPIiKuRL3ePYN!Gpu#Ց?M2|Cj//G7B~g4 vL=֊xt#Y5IpbL` 6ReQn8D9C]McK D/1^:L? ;ZO|b}_ىfqv +Wև}3}AdsRV=:.-n}jDdߥ݊N;;sj2bpðLaL)sYiҮQ 25hgY @̪V"*]^!4߸1W0d|ꖣ4XyN6tx3]<酈3zR |DKYBoU/§؂ttЙzakE۩9=IM73W1$@Gr-g@"۩:zk3t#R4*_V1(z*SO-tP@t{®m-K~EEui@uMϟ4MA1Sս4?(A% 묵R!y\|:E`G0Ɠ/t p ]d4Аiг5}AZ@/?N#io8%!~x bZ,=)t " #zZ- Kɩ:OtفVKdgbbh?2"9;׮O}5:40%QA^y?7])vWqrUJh??ȡaki]a\ADc#]NP]SIv\Zkuަ%JnPViҪXͫtvߪiVr{nJLiд]ڤ$YŜ%?x3}Giv^~xe{kBԢp.8, A;F#-\ΉЄ.Nm S; c-bZ.+"`XAou9 a =$ʒ,F]KA Sl<(W=z?ٟy!]ɗ)g_ ?ABh?5c޴pˈ+ ~#-s^ :1+i4CmMt.]<::a*E˖Bb"3)30J@%,c1bT%ڟoڷuCKwL?ZنVoy_mu`EP& 91};kPpSjMV1ht;fB'M{ؽ=t-B퇮 ]?(Nqo@˪@QӮ, H/ɯ읗Eۅ~n8ݼSzs-J`vh yLL5tdqX-KUv74Ti p/^]8Ӌ'bw=%y 6d8Z 848d'/m3Ϲ59m!^/Wo?~$+sƷ~kAW=fbU$kIyR$',1`D}7 YmJpρDLcLF:,oJY_gA+!7Ue#aZ=p~X_u7o1ݮ4{{W+mW1І&Bp!Ҧk˨d bF};(KEUrZ^O>)4p ӴANvgOvg{3)|V%i@thlq wiC=Ȍ>JaKѳ|䭿~sbv8솛;BJrXPHΓV5ZCW `DCD g߂~BB"1CxmzGc] %. -(P6NM 5^L.˘Sc%z\.%=+gBMhs6B ׺[!MCtu9whbW ӵ0-RQ(JcbH^(PJ"Ud?îIfAM[O*n) SRa11"1p|4Ѧ6i:yjKum]QJmGW* *t1&h0䲍| e_; r"׻i}T zw"4O C^b ]R]TQBg镡=&pBWA4g*~ftάp3Cw(PyW؋a P.Z<``"`ʸOUm=J "h2Y|/ռu;׫! ߾?_#0޺u||A'#r96^tut;t_/ޛ{;1lKN4aZ-ކUYF lWi[6IM^nmD  SZэWw޻qv+Z11 p2ƛGt׫t2Uȃ J/6׭Q:grݖ: /LCX b$@edDU ' ,rJ|l)3gs/`U{sBO_LR+@ߠFNZ!0g*<^m{*YaE#+ӏ+N9nf&85<E^n_,4vAYg(k>GJc#cwRZ^}In9[QJV@0IðIuty]CmluBNoݺs畻޼bPtVԚ>8(isgiS= 0g+1YJ1j 4(:)6ЌhVjǦܤ4;5LYxuŎÅF u8}QSNx.)"Gsnh<]|ߘD"qq'uJVwSi8t1̑v*i<$4U ya8A8 ? )M^d9 I|e7?2 }B(g{"dWqCHg_)jW)f}4sNOo==}pcsDZvQedrs3ţH#nz=e1Pb}pyH=5NMBM#ji:3;^*e49j 14tXE)a'%LE:暭ջ-|䁜=()jOsH'a8x2tVPr(mHpw nρ, *ҢS?~ '}A3 5e!9,.kFS4RWyC"ضڴN&ܸq=)RZüZ{S-p~qt3of9l.0rt7lЃ3A׵O$5q3d(9n h/о +hPR+z}VA6 @*qa;)ߠ )sjS~Lu[aa! WN΍I#NꖓAcJq)v ~^r۱ِ|lwJK\/VK#uW C)Wq<fi@Zxsv.UJjoռ?w<0ONF484;DZÐӐB IЇjd$9p< &pAtdU 6sAXSO6RV]-fnBm/^ t}ӈ踎c|=кo6HB N*ZDuwY|s   sZ1{p:"bdw?ĀDK 1H=R,:Yf}! Jqutt;͡VCC=\0![Jܓ؃ȫ4uk\v1se+iZ+u ϖz֫l}8 `iCkCVi=XI o WȱY=a%?bXf4W|$,˔sj\;FIAI6NXѱdA#bHV SXkri?t 1|FC- BСɝ( Ѭv=aD]{5sz8~S&?\`T;WClt=@@h[xtjVeM"S6t9J֗LSU-am/ߓ=H,w4;ELʁ{ҭ(3qjn^`H1$ &9ftt4'2![h1mۋv[[[A1(ePF,M  y>љ.Yȴ<84a-Jt'%*53!ьʼNۆ=f)H{oTbJadrL ݅1AH)hC$C6<)9L=cY2bp 2!"dYRj;IFMv;-bi} Fa iGxۭY/rG~!T7۠O̐-Pt&{*)1u5PSP/]Ӵ)cg)T^,*ZĞ: oqؠVih1bfȈZQBw^J  g @3"ҢߚZdKV$n!Je!u+9I--U9>aOl ^c~E[C6pb8)Z|l dSO0źρjV`RH76C!=OQLd 4{My΍;V'G2[4;&9Hpuh~g0ҴLl8],E^̎f:_}>Y!X^KRoR'B҄n5{ҹQ>Y_ZZn!h]ikd ~yecU(H!g2S cԞsO#1 4^ 0S,gtj,+ 1$J*ku ~7 +$*{77|O z& LZX@Ma# 5'%.àњ>x`stOquc1ٕ? J MpVKz ͊.մKn4 \B*2IZ*F [rBbr! 51TY)1Dʉ)YhE$ 9sb4d%S @CYSedNYcM ƴSO8԰̾L{e<BRYw14,U͆!94hT:y=ܻ8h\ot`;DREW6Mqn~ख़rm%P Xk貹 `ٽ]SaN&16$WhAelB۳XܦB+,5܂Q(:Sȝ3l 'TPl91OH)'.=PwLSjC H:h֗Nn_ y|H i{ `Psw@t{ :LW*P 3ke|[դ%!czXU= qN$< 5ns)uR+bj+PnHchFwu%BK<,>Ef1깧 7ԤvA=%C,lI4 &?CGO6Lѿ\KB b܃.dǡ g<)wTH)Jl#`wK!ﺠf. "f4$Yd#]!}2X4Z޶tm[x}Q #ܺmo+Э&S#3K;\ }M<:a6zޙ8s eSGoC(Bꐚ`-'9 ca>[DD{ i(dѽ1!eR"!8w>ɰl}YwTjm&T ^pՏ"sB iC qL&ֈO!#PE vb^?bIaYe ©R%Y$ wypjh+:Mf .&6"ͬEQ*HQ.9b %TJX6GNNng? y3`ߋZƋ6 0M{<]sq_sYuDNl!WSe 9PmϬe\g:M}z?[z-0?evASYUCЌDBbaNųF1QS âF1jN8?lW,w 5vr 0Pl?"6:[DX5 !%vtf,a[M1.!TI '笢.H9"²/)  )u8ڴ4L;DMh.CsX/j @rhXUjRym)PcR=~9yj6ĴX{gņcWlORWy}ʫY\kIr/x=0JSZaLØA`giNXd?!orNVzJ8.s.,a»t}jr(E=udlIx>A?WkMPOތ&t]uYEt` &)B,0"44QP5_cx~b{w^w}N,(u,(vAfc2t9!aB#&^B0r iGǖ0ŝ@͊T:1ZX8Ii㈁`dƀ$ڂW38 .nDۢi8`,{sx)Ƅ^hקweh2^*=~z;(7XvJ'afL)h{;8° 2r C?Ui`'u Qx 98tй'P;)apoWAB|fQc*b!,ZnIȵ-5&}~O(ZS. u1I͘meDb:jE+ Q`<`))݉?ah?$EP`"Qx0vgV` 3R_dc,VJt)?<dq8't~!uva@15er R4瑏D#5A5v (yDnq~ ̆cL7ʈ(o!C1DZ´~!,0}gBV>bgVUIDATt"Vj0I >P)0aIt 1'c}"b~K0`iX?&ԥf;j3vLj.c"^:q4Dem=wtFJYk8D8F܎"2 2<`z)sk+l}6)Օ ;cWnFQy`{p !MM!!t;^=E5Y1) HGDl@CbQ@\ mh>ZтmJ ZQߺ|*f-6ho4PJ_qȪz ś kK1B$ b밉K8bn CCpRzmkO\V4Ak"q\xȌVs}.b"G=BK2+$Hv~WӲa3"\*/E!&tn3֫;#A!Vkm4H攵{3SdY)$dN>z~v3Oj&ܷYzWW oբġ [^x% `پ" EbD\8H!$%04sB[^- NQNA0dbnFkJX sq!d˒D?a@S\hȡb}$NMs ]s#+`*rM֣=Pѓ@T =g^F Vv:FpscnQ -;i+ -.jXݨ6ORRk? d, pYdlN!œ4c9!>/dl`0|/%Z[$;ngv!@$x[GQcx}떎0>6[ُE$BAZli.m :`E-ljMIDM=)=iZ5\?sj*:_D, Њ-._O^u[ UǨ52"O 6Y ">i0/o?5>juQ,|%<+ '{GYrqsBVT2|^Yɟ yͺcj,ܓI>^mC Wቢ:N`RʯHj˕ vdaB;*[-nBԧ%6Žecu,bĄflh2,;lבՏ16@(z+U\ڊEcޡ \M`^x?y7, b 1[O_bY?d垳q!aƨ=a/0t$aTb8 s2vhRڠr\l-$! VP>`vAB͵\RtֵXvAZ `vEၥ5|oB8]@JSS&pӢp-AfKfVKߚM'@;W3&hrȉD]xH{b5jm/f(H0YJ#ԅ`XHtrz~VᣤE,U:{Cly>u\zbPK!Ƞ ŶNiQ~v0#cd hXҢALcD#[B61'`0WOUJYl4E8s(aW;Y:2+do7ٶ3㿏쉆w:ϷΏئ&6n$%0s  UOČ.lbQt⼸q,@~g9{i3g@Untę,)Y4u麲̏5:s]p8DfxT]%fLb\0bcĀ(q",dr<]OCM|q̂taY$uuIеSgYT0Zˈl4ޓIscKzC3c:X-a}io73{~]ڐ̎ougѤ ;>IBcA0E.JfhE@w I!o BU,:P jV!ˆr8tXzfOj1-{j˞sc"2}=.eӐ[ BV{Γ $dTa1Ugm {ݤuW-17;'!Jq}#HVF|^W 7|/>ZЛԍ )N|60ЀN/B)8@zY7Ķ..˫጗4#YEĔ`pLC @AWqVci=HHɎs#3UYhQ>+ouMXkШEDɯ&R6-[/z{w9Z} Ä"P'H7u6,anjH+b/S!AX*"kGF4E8(9ٽ{)q1́u 2v̶Wk3 DzYd3Ld7 (NqK˼cOR{.DŇB/C6_r/ϛ(bף-&˪RZXj6h]zAw>?Ԟ/7{#IبV+)t-Nydwܳg,LÐn뒟^ p$Pfpk$ 5 t7㈀D&J*{)aĮM.ױm{|~}E-hT rΖ(5wuC,dTP(8P'7~Z^B a;\fr{mj6Y:XUㆼQ$*R/iysҏk=֚z!2O>D+dE`4cR4W[ AO|abfk 4il#8*Q%|Nϧ>V{+$>\{O;|}p|l.K!U3 @eD˸߾}{-=;=#gyչGڑO 2JŰp_ysq+׃\,edITK=*lYuǕaFD ^OqXk^3KigJBkU8aF!B#;L0."蠗CXrxFk^pB&`s,6 v 9(~Q|Qc`)񶭩u}Kb5i3zqR|~ l0sZơHqE/wX`Ho7tg+hx P1ysK>O@ዏ*iM339wx_QZ;#Lm-SujVq !ħPERM0G!k) 1y@+J@4h$sW+P(S?ah %5IENDB`gift-0.2.0/testdata/dst_sepia.png000066400000000000000000000721321513354670200167470ustar00rootroot00000000000000PNG  IHDRxԅOt!IDATx|muLwz~=dSh5P_YX$ NJ~5@D VX@ɲHQd7U{gCTfuk}g}')8bcRcQj 1hc)0Jgi^TDkH/ajm쫴}!1ƾ|q9~"GQ0 ûُ;_}Wom>=IA+ !xIR)cPJqJ1 @ &pn;!_{!VTUW|;$Mo>y K R+{ovyVKYucrptqvyN~ORJr/hc]~7d(ц1XsC ]wonǚv"y~=K9gIJj)3uc.a_#{64|[Ro4&4XLQJd_ϵ1;kG㢬@dy\[ }_yۏMO!Oۄ_̗im>y|3ònW-e~hetQTyQQPtQB0-_/$TUR(ӬTZajEIBn6^{pwgk}0.N/hXiX8؎'x(Ø݁T+eoe h yN%_N[nێ EHs01.>>^{^_oG'_t%9/t``u`imv !a(pݭQAgc9ZP A9ۉ̋r{cpsgk_NO/ 0@0фKiRA@9|@!a%q72G0fΛTk[[Q<^Ob{DSKWB#Y-Xn% ֏PÌ/ @hadSBLR*&nݛ[Gb tU%<.ڭ_}7 Ip[1mHtJt ($;1&BAGEe_,Xvvo{,o%gr<}&j81W^{wk)Q*WյRRٵ0{qQ"{.Eǎ>Q( ڮCJk!rFki47]MM|Sg̀c0htvؿB-µ @K!8`.̺[ߎɋDOq=6ôqdwEND? Akj"Ȳ QuEھOvR?b:"J()DWtZ+wvnm$Q8[䌱A :/*UU.VYf Jv+j|T- _%7ĭ$ &%G>@q WhsOBIQyQ Jf4M(sf \Sme4Acu:lgh`lv1F`!1DA;o%;{'g4/ІҗSc,i.^,g, _uǟ}lEn 9mcc欉q;QkG}'!PN9[Cv^X 0 ,k Zڷ6.3x$DA7 8͊8 ڭXJICj*@Z:JA πj,>l}1A.<7HZe; ŠKRR!+a:`<`D K0I!w:Jic؜S)|BWY]I+7dXJ po?ق:wvf(TЫckYuYu-(b B'N;Z[n#Tq{w֍AF8bH,ʂӀKix:~[V`/9gN2tI],˺DR6ƦثyX+M@Lo>E9o& 6!lSqoOTƒ\iPLs vmel / `&r?z0?Px}qݛE|L x7wϖ1S/f}{^M愘hM7$1S`[^3ߍ1y^,.`wonYBY ۛajYbx@D`e%*x~W8VVuwq+R 2ҬHR*Ռ JH:q. ˼:LgrPA>ɗ R-M,f'5E)  7ٯiVYcklnTY'7Oŵzgs΃j2GIE$8J,/IVd-߱!AQ!6(i5<m1BA8 !o6 .n Gȁqi9J벬>,&ۛC-8q|Bl ׬W@sB5ѐb`j w3u)\a(ˆYhMKmj5LƘ,/*6XZh`(MSFߺ}r9^9BY$i0f.2FXܰ>@"Q坛[n sH-kǨP@ [LdcؔU& hA(`9RY+ HeI9q@t;@/({;k;(+bU :F@J 7ٳ@2OA6 U 8 4ٚ0Bd_]!5&kj43׋WSim€>' Wk70BF0%~O CL U a&)!Jb4jSح 8 0fsP(Xg%1Q+lK|LiQՌ'JlRG3G`Gn|W:M?WckAHԵLrs&!jJ ei 64n7%t(@kAfLKa`1̥68Ό/qf5te}7ڠ{=Kk)Rol]cz#)`X3/*\==*4((C7| u PJ(B 덝5@p[e}mދU ݊@ A뢨,ą{}=]7G`9YF0 IDvl*۔Ju_pmH0Z8]8"BBi&I ㉨MN_@ZcQ?E$Gģ(/@Ca+"y5qc@Z{|6t[^%83 A.J,MrbzH wSD /xyh(  rsai V|gos}؋c{: "⊼@0b(  PCB5i$vc;xXh5F( v*t55p֯bv+t>Ñ G l„r lځc0 dtj,k+`d, H\jaED](Lp!Waogluu/`ډ=|OfEZyd ~nm/Bv,`3V;[Q`!A $f.֍͵~ۊ,k{Kl뺖0 v+\(+Wq¢@䳈o~Շ_OтKql1$mZ0B7b* M .PxqY7jc"u`'9RC3^Ӹ qvY~wc "@ 4Uk4' _d N4 kW,Ok-ҾR,/tU26KtAlD󽝵' fS2'ajhu0`~=tlЄ\DUBb[I4+)C0jRɏW<{yVVunMCd6t{K_PΠ@2zŗg0XB4C0%m2YX:'p`PjP0!{!d1xgSkBco5dGA,k~?}+Zi2&'4^Coz*g>sT1i~#&V )y^UTRJu1Y$pP'il[{+`" - qΪɳw޸wx~bBR _VTYv6TBQ r ΁% Q@z:ϬwP&u)N@%^\_gW<hfY 6]J iCj<{&T:ߨև'W `Rna ۩bkǪBRHwyaY DL􋫩Rz46 7ԙs(EAyS ;PN+< g5X 5E7 z&W i' bGıEdi>6J1-cZhA${;?xQk5S 13 F*=#mFZKՊ"SZ{]uagurSfFQj硋R^LίOONWDA ;V9cfB$+| 2u_Ogٻ_s_}pxry1QJgDyI܌FE} BKh/Xmʲ&0Nlo7T1ߐ,Hcp(B6 ⠾Db z>p9h4a,.x36NPyMwr3$$N2aFRV5*0 zmDEY/bgs !DlsƠ5pTڣbȷZafUKxxnEU F//\ gݎq)v$-&tx~g@0KA% kj 4jD$jZKU D $/X,gq%H(8>YU0$ :wyçU% ZhGƅkׄ3.kn Bh5YQ"붓&ZtqTYU-+ ¡G|?|b 1 K Mu:@p`)DI =Ea`hbq3T Ϣ" gn 6\*8 !z4XJ].q~o܆K8$YA-I$Qy`G+]\!:o)fZ(/'wv:TJۭ2P|pڇc>ʣP v#|yQgy5U(YQ<"21)BPJ{@B`svz>)ʊs_{{?w<\Ƹ, B݁kx(Hyc*9 WXÍtX%q.ЫW_@|45l"ONu9tisR6F&zAE@;W8c$ v1" xvkw kDQV񓏟.cց8,BHYy=K/dz;77Fv+bB)y%Kc#jiV'y[H7>}2/8Y4(4@ѓ! A!u(N+/'9~K >l<.ڮ'b/'s`}u!P@0L˕*\ㆽ}p,Nzu-*18@ NQחZ\'*-byʳĉ8kOLIH5_y>UrI Nű7}lh"Rw,_;d<. AiȰPqTRAm8*c[I~%BZ͵o7?GOlmAǀЃhdzEPu=],aZ[A5W\K@(l7Z#dNuӺDC 5@AKe# U%5"oWD0|Z )ߌ6M1p`@][nHXnC"8?<HBAʜtǗk>5E:ҬȊ!v\MfѠC0 EOj|aYηd,~(M%Q[J,4݀6j2?'c,b0i%~R_ qNLa}S : k|4|!б,묨i=bld^O (?&q'cAIVِ8,s 74n\Dī!Y$UY* /)žJWv+6,Q\ i86gKm@h;˥7@OlƼW ' Kq_HOTYN"COC^ bJѠ)[7n5Wa(9)];~N<+==r.A߷W!&ʇO^>y o8Zdb]v$d|&m,lj̕BS"rEwv3"zgS"+8(Bxtm9dR߉Ӥ>P!B<#oE"KVu$a]x @Ay^  y(Vh>qVjw@f`S{+ç/`)Ġ0J1wf+w.Ƴ]4LS`#Fzqzq>i͠Rp%"-\d#i{ܒ6y^^`#M;B̺"DBfJsV4 Bh!F`@PXwРPة>7nwi%d&_ylSFEpPWJ3hS2ѥ 8%)Zq lvXWMCT ]Dk@Wc{㿃,9"yp:-1i$Ղ]|U%)TRg5|6좉JMi`gy9t= 1n0.3Bntp1NIdbi~r>a޽G!Iv VX|Dƾ2mg !CP&8ܼ#+?:<趜qPBV @zG5k B-POi&@ z?J`qZ2^ՂtL hzPK]4h⋆!Jõ>i<˲Cl4^LڭR634^'ypw݃6 yIUy ui6BZ+WlyD0JC YYu-7&1ʪ/ѠCB N⺸qmQ7Af8T L&@jƛ"f9N*8(vZ\ѨM-@ 524 (Fp CV@!|vb+Ш9IE֫)jP [1 )t>?O$/*uAL^>qV+BJ僳y>|(aZBe]+Dh?ǿI9/G/J[o t4c=?,bx>F T3qQ N kD<4`ŠgiGa^T瓽3 7+mtx޿u;@܌QA}gͲ2qÏw}òa,r f<$H 5/+zz>EYÈ_}.%h((=T)~^Vȅ4w̷\ǘ}0yQe-kAr@#y ! L\Q`"eYO PHCCێؼ%|9فiDC0b9I39aFUqzb8r8ܾﶨ)ȕm΍Gʾf*DT3o^pSA}&:Ã)pب/]5+ EcT^T8ԛBh3Ӣ)V+v~{N%Tktm'xvM&/3z(JFFn,ǢIu(Q KP")ad@ƂA@Ѯb$}ӑ(B0z3m8qmʵ'qDᇟ>~e]^bx/nXݻ.9w ƄpׇrCƬ㠢Ph 6:ݲiaBZ 2eYw-X3v-ty:up&$59LGv:&VI9<[p6-#TbWj8l [,/}%tLGa4ݺMBXV+€"9Ӵٲ3!xӺ"B( Vz_)͋xaHQIv PtL^b覎:Y/q~ıF*qYRT! C&EnӇNR^L"SJ_n7AP#Uj?8xnE;ò0Q#bgsJF#>>xו9tXl eyfcRr6 a$uVJ04/g, rդ]ilg{7~N(hVD,~t_:7 M#???Yvo6$06@M6ZknuN1T27Plu8hz2j7q2Qy+*A`e];8Ӡ ֵ/?Zt1!H)}xr r{yR7=i͢p- `hR `P] ۭڦYbarmMw6wKIĐӣyjE}b@mD4GOt~w=%>ݭ,+won5^{ > K\놵 4,$ =MFbL4`3RPJ:&DUC'T*M<;8ٷ0($S]/. E 0Q@cE5)r_D5[Cg^\M>YNCc8+gi0Fo? RPrayoޭ2-Ya@|=K?;h, I)]IdldG5tUC)@ 88_ k5 hU}aᇢjdEy)Lhd}byQژf`m@W*8:3\!N/ " ( YGqQQg18ܭ,*qaMQT ܕ'N|$ &;ߎ(X@N@>9^>FrB{kk}O 44O^]MU%ki"G18hkn$5HgOF`* 1ER8v8G)8GJEtIewBXU;^ef&&UfcB7`;4^_$а_g>%&rGih7 t&2yQ B0j)VqulZ^MJ7_z)XA;;Qzsm]Ewh)x4 ؆ih7TJ~N|AF_<ώ__4^j*la 1  "Vm_ӴGy59,u5zv+\pHA d/>|Q7L˪xv8h:ˠLhjY/SL J>i€֔1-;J-~4햌Ѫq4Ʃp('10 qAOSrǒ(B<͓YH󃣋N;{߸yztYVrȕV4ml gp(s\K]##Q‚g8N v۰P?fw/FU/{ĺd)%^$Qd2K[!'UNk}ԿwkkogZRLr8u:BЃƘ73?KAeTC^AJ*%qfW+>\3ↄ5 i˲2C02`}ؽ{;kpW ?d/b}S^LTv^4nha2)!ҵ['%`n37` 5@$#+( V Mx:OӬtW9zpT:, 0Nu f4wFsNʫ7o=?{qx~|6.˺ӎ_7(kHQCklEU0Z1@>Û/"~襟z2 .lx솔=.M?iY`dNhtQX1hZcؤ,kCοn;nor=?e$،nykZ24͊,SB$cMǦX@TE B Ci[s/dzsl\(?{>tCdDl3WzD} 'q+{nocGN-@HygyCpT3$͸ 7Űq˒0P1HͰ[u-wPd>fY@K.(ܬxw,;A Csq5M?}˓765nCYzEL<"R84PR@гgEY^6l (̊j{sgJRFK(옂6MD>vɚk~޲;9+Ra x ,l;MKPU_9g5[J^y}yҋHؗ f{shi1F"сɣ4/U`@z v#Sb>M#MrnQsJS" c5 qD+5)A2#)OpqQ_յB7/i=|rޏ Q%=a !́b= b_)FgE6Isv)%5;_s?WgjWDdꝸo"7 L0+OF(h붐C15ta OM_3B:?43nklEJ1 a+4= M])(AƋd{1]ί['^/vL<[<>v^vs|jr?.^#d*g@d<æc%ڄ+}#KqYR<>oj|GmRSf *dUpĎ^g;ژ6_䋬`^"-J8Op`_-m9mN[A?aD +p<<4auxb6QƷ5}' KiRa |@ݛ[__&$ǣA'KiEf/NjAcK>2lٓ#k0aoXPUbTG!9(vVi66lw&BǮafE%EUVH];@eTiV zNEfVa揞Y nm&!㍚j>8Q0XE\Ju(NG@.C#֍З@Lr/q:Qc_wÿγag*ZPak~0C鎧cNЛE#gZ&§q1<$d-rNZp|O;5i(Ns < Le GTi,@ptfBp (%)!\ xvu)j\41i; Ops߬,DӰv~*讽&U]A!yot:ڭd><² תeΦ( F%ݛ@IPHfBqeW"]6tãg8Svm[40wۏ>I6$:jJ2몋2ns[# F !Ctruu=wO5\NQ 36#:֓EZ`NbJ˓ ]AWb3LqpdPK׫ɼI{n/EKC]wi3FTGB&pEn=9BW;À=|r %TO ~r6A8v FsܨOG]⑹4 ", 7ki\J7 Nn`OM6g$rwZ^of;t׋Wu/w`T*ar^3ᚐ)A! Y3gH3O3ݜdY\8{ͳ`Xp(wj8!,K ́)$BYlW_B7d9N aKd-)e%N_.DNbS 5$^8P468)dOUvGk݄ۗS V ٚ 80NBm`l dhȸyW;0V80%VLVm[_ڦmծi.ҬD6$tNf)֎U]7P`Zz\:EgA87w!i^H9Q mL%6Pzgc*Χ ĺD` W{!0!|%Dx84UAɎ-XrH@4Stzz+/Q/Љj*Z<;>_gyQeyĺ)/1rckCG-,( r^EQPUA[ ZI$ϲvwFE֜fJ x\S;t}Ej9`؝&X}3; 4z>W7'hҥS+Ѻ)8-syswO_}0.}N > J~xr1kw; FUǡQL8ʃsOްܘ?eH|yucxCPӒȻw; >LV}7њJIPڦAvT#ma͊^봰qc0QԵ l?1쯦]NK;~w_SwVWY>ƫy4m/\6nCBҺja(xz%RDc)oJ$wΆ0cĨc/~3MnRŬijNnjAVUY+&x\ͼBt 9g#ʚ,2V] l1ؐUŒ&/cQZmvjG) $.P!>g^['eCBdKiW'{j˭oO@f !1x# ~ٌO_?wL6.d/H=X{vnm :"y9VGOz^18ź5 {{K67}s2#. (‹ٹ1"C.F lKgc~y}ĝv+oO"BLPUczxhM^6kn1=q4+,p~{ Wb'X%\=!ӃdPLJ~/wÐ.Fo0+؜~}ۂ؉#)a۞Δ)3[ $-eA\b_H?^-zii+H)BGSxp%hIT*[:'jz >;ϮV\$ Crs?C>VuMzM^ )XUKxq9)ǭp\Nt4Wz6v1{\q2;c]jtb,i ,Ka~#/$1S![(jtUNZA"x>yo{7$*JPE톳WSt* 3<d0}|˴pUaJl'q^%XΥ!+X4yEQBsLL!-Ows~oVֵE28}8SZHnI2 l;g!?ee. LZyYSeJ 8QE7pz}{=pͧ _ێ f<]?cuR yZm=h m4˨X4K[&/Ցj3MVTn+K>C 5CHAj%& HS6CUN=Z%*8J@3X2]Aw5:DlE&ӔJ[6yHi7c"xxx.F왝Nptaw)X{_]K+?)#Emclfzxgl8)OqV k`^\ }[0eW -`/ur{ZQE-.] \#~S\{t*TcFarJVf܇ ڭ]q˝I~;>|\rQ,U6vV9fU0p@"bEgŦ&iD| HA:d)B.w%gHG79;9?,U:hrІD eJI(}= ɚ ?6HHUΤTCgUHZ{N8`@FR+X/1HLz&ߓ11 WmĢY˚KΉ4mɚ8żSg'j[r|ꆕ@lTZnE(NFx$9v*"TyTI!҈Bgh/*@Ony[FKF蟼눃黶Fm?@;V:E'Xj>fA5jZ?jcJ^X3H,x6Wo@!eIEޤn]U:!:O;qs FPMt8^ޏg>"iVZ|C keĨ/!"h UY6P݈ךZMkןm=(ٚ2`pC@ɰt{oÔ9pJ"GF*DY2'-ԂWfm!Pi5)5@܂*. F[PH.rPu◡FK sazx'9a_iK^Ⱦāw6|[|aoޑ=Q:fDSڻmPZKX{O['·AԄ*%( k`a"=h(9CCZ@9 90~IЊ%Pi&&4$V,feD8}e7Mn~xzw}KqUpq3Nabl.dej-{tRK6y̠+Mͳ~9AbA&H.۲ϝ3u EVT*1?"\H27@DZ (!8z5Eܺ&\\#r AI•^@jX!{W;(Їz]kהmYxO_no͈cK .YFPC&6x2tp13yyi:cq\dlu.Af3шM6(++em=+P*9|0z>O3Q炧؇ CMFg!K -IsY͢? Zs-+BE΁A|/U6Uk9o~40U&şZ=kZ{ts5MWEv&-"Ч]ty~=!=qQ~Ejj ;A|roYdFdqT}R͘ğ9Sd]*A48b3L/;akuEut",CZqs[HWS 8Gl'e!45XAUgGD4V ``ZVR~;az4 <*4ǐEnR&cj2[!DߜXO"EsCpBʘp +vC實8B)TYd{2j%}l] S2iߎ# vnɱ"jtx]e"zDМsT.uj?~Wwq (8Le-[L2{k d|ȳ¦4R#Q#\/N^42٣LN\4*խHK!TD}=qR#P R 5)W ө#b [?o<6rcYZe*3Og>!x[koc0Ze $~XZ^9IH"˧64d6kII'=s%Ӆ"^0WS1!AB U̠I8:sLm6 Q)ܪvP^5$n}\/1$U}ں`BLQQӜg1#4-,gH|2GXtϻ9шp~;^URt! R@5 - =VEr\x{S. _0h#[ CRXtQn cU5(QVTiȉOۆF ưX3 %L]pr Y>SS1ӆk4́+זʩx>OKgK,mՂjjIװCS#-RK&Z&ǐD[ MbqxS"SĚSp:.MsoO/G[z.\'!HpνO9o6ou耻rb` U&A ]zW9Ovà%TM3L,m ()'QD<ڦ.*^͛G X%6XwCEXC{/e&AxPf9;UʮhMAS q2(شm6ꐁ∛AQ/,TAU2HM?%MjRv%O5>d$ҊaMh_$>P=G30c*T` ~ C 1_:B?I6Q.uK48 s@z:h%*&ecd4`$n1JDx׽FU)Zf)xTIR|#ˌ41{HϤ _/j: Wyv;"?* X'oDL/ BTDK3V'd! ^-[{Ԥe:=fYZ/=mr"TGͥƁ$ݓIr\30A)j:S bCi6#B}Wx!fwVq t`/ co1gp9d?g>[N 'JֺߔERahEM>Ba1e&d/' &].vVҵ{m~r*Ltcm@D'qH?cbT`AyG"G!8O~e72 %j3D8EPXAF̓ @ĜܸC_ҽ3iSѧRc2D,BPbRO$а8A΁2voG[ɺN̗ \,!/,kq ) ?pCآRO+4YLd+an>l5U>$bdK-qԸWЙRBQ`p* 6@b}" ?`*ifлRs,jJTc D](V߿S3C6@[*cq[ ̝4 O@QP$a2t  (V{Hb+<.) &:9H, pK#"G]mʓeqK:st CHWImq -wsz{ѩ%a θ~v3dNq.N9"- ]eXsYSXaF8_CEԹǫC+mO_(ʰaDu}0nH?x9څQ##*`@u+\A#qH 6rP2d`1ޯ^v5fݮJ2x6 1f.ѧ5wL_'lXj;[k%@lSˆSX-9ˠTB/.R'r(ZZjlʖ5PGȧE\KYj$i+H1]/V\'MfZ" J/8,q4c]'(@O HՊv} *F/YԈ8t7cδʊA|jmviE]+@鍫むL(v@Osf>{U@JXޕtNgڬ\:⶘_e!vL,ύR|RNw*s-TGҏj<&X<'|T[:[EXϐׂ|%v8˧n<ߞ^wͰߍ/F#$Ts]L E;HҞIM% 0>goq.a t$!#r _4-8ruzQE ȘxX+ (*Чry,&YD]#Ű \xRp6K ΃Q͔h#;18"/zbQKS*oWLe C6{ZٻX:n\`!X_(5Ҕ*U|={&!&ؾC6e;|ʠ֖z<)1 t)ŭL·8DK+ PkNum5]['Ҡ}ԻKăA_bZKRk4F `p+uMVLCD_됦9Sg ,TA|sSe (B D1`3Mhy ̞d$/'bV])RܪQ TLfz/ʬN,"y7\x&^=!.禮+PZ ={0V'vr__ݻ>NxE7vt(+z_ގ3֥C019*uV@/Wct:oj`^IbefM?ؕ'DiqpR/ji@~Lң Ef#atyGZ1<ۺնl,e1*!i:tF"8jK,|[Q[ͤ8"&SNoJ zbݪ%6˒ PupPoR#I͵DSh"f5)ʛRX,EY\bi QBPr=)B=Z.9ۉKΔ+# t2@AT=uwdPgT D0Rw0xD55j;3'~Ѷ^( ? * Wl:IENDB`gift-0.2.0/testdata/dst_sigmoid.png000066400000000000000000001115151513354670200173000ustar00rootroot00000000000000PNG  IHDRxԅOIDATxTieWvk}ΝիU,VqjR-w+nGj%["CRd Gq60 1'QlRRjDĩdUyz9gkk[d7wa_V4ƬJiP:`f СRy܅yRZ+iJ P tF⌜3pVRY!BD,*b ΀hڑz4HAB|/ Ͻ |?sb@q̹8CfրkBCDX30(TXGyJ2l<){wիW?|pK㗾KӏߺReB?>5!,'"7^"/_RLy fdDLP) 5H[Cu("bJUd?uյum@ČF"&ԖȒeQ+VYRPS&d\b"jĬ4 9+5Ȉ-*Y!S$ F*p*bQ3*{0nj:źW`46;?>#'yQ _̹Qtgobߝ1hPAms|xރ㭍7>zg_x+rPNnN|R2S9˝r(*Bdkuy k+vόW';mol|XW b"bZL]LZZ%J+-F뚰fh:rHv䯵 羴S~r;oh})4S*LeeA&5l-)ϠxF1pI:gS!ΆŒV2KbBy/_zm4у;FffIv~u2q A9$~[<&Ϝk_3/wo?86 SuQr><{6*PAA#,r4)mЍpkVoXq)\(QXB:>]8̵/n>sL{d5 !}pR[+g9݊0ly>BV֐AU֊#EMd h@љ3/>xͻ7ޚ$lMo `J;HBg&"Ѡ|F I|,0B}X`%!%l"n)d*uVݹs>6zȠQ/?GΟRP d% }l{~K+w{Wuズ hY ОO3#[H@Vii;@!fH䌩i[}gNNGNYU0dz _Y8{շn<9JN(T1U9 (nP9PN=jm +-"츖Y)B"%D$IP҃zedBD1f~(6 GiELd$d:.bH1O`H ]|'Q3(AkѢ DGH(XB i̻_;PDս?x~A$sGAΨvWWνo}iG6rD(l9VV-ЭCrfd̠Λo|x}S`B0V܊fҘ+1c 14)V y\1[H]$ Őh},)Zpj~(g9Vy]LA6*)BNg3c2 P Аָzl8-i`ohqEc{vsU5pjB1*BD2!H! l!ʡGd\yam}pNӑ a #lb,ދb -Tk{PhMFHh umc2d ʙZE1?x֭3<Ώv>> *JY exe?, X VF0L4a̾u }jbyA j\ ~+|*h%SA҃KfA4*2* $BUb8RQӓ颛lUcB׹`D5qB8>lOd`uhW&-ku z9&MXQJ )(z6owOt-u]Y@Act<"+ztLB.eϸc (("!2\ (-D$>hZGpZF\@l6u>޽wxͭs[g_luVw6u]5Z eT׷M._tiʠztサ%crV,IN HwB&!H٘{ !r1aPU@֜js?}2=."jC¬rɍ !{}.9jI84\i$'trFZ"SӚM[5 hk#X70֒CQiJ!޿p<{izzr|զb dϏ'k;Wjp֨/{s߻nBcNhs ɧ(^NXQs($wb~Bm8YC~ϼUts̡ yhfat3X F 9qBhs CJv4,|]ء?LƩ[h:0ihX]jeCP ~xpgbg^jn8k2m"!pM\slhc@5.ڣ[7gGg=  U)$,\,"2*K>A9B$% s d'HxUkWzHf`E]PYL9NZDŽFݍw_z晃<[x߄j;>0,pBi'OV ]5=ū/~Qw8SQYA҈pbB`JIkE4v>"#йg^8!C:ρA1:TBq$@45<ȿ j X#1dU$3;փZ)I%b550Z5oHs{&, e(RĔ}bG.칸Љ rbEYx0ez(A 6 JAvVְCȹ!i+3£6U6YAA%mhxkP3;Ӯ1 ΜO4(s\}yV*J23,/'LCP'BIE@ +"ۖDo!LZ *S ̥kWώ>;bİy?OAEC8|b,D2rhZ esW2x6aplM]Ut\]Wr1nOLLIuI(EO8)U*C^!y]AY4XIdQ܅]r(jQĈl EBu5NA@J{N{D#W׃a]Z,Qq"%Rl %! #9NI3y/qc6{n֭9r^4Up$K65%ɋbMon8%ʧIXih\ ^$lIjhG\}ҕVvHM ^$hRNUabA3VVgHFX}Fio$E*CVBYZlVnjq"Zt %bLzJ3KBC1 8]D]5EXZBZƽ;c|@0 YE3Ao-xXmN!`h `XU2"MEi%֤zG4dIkB=][k=^YYO۰sَWQ[*ٔnd6O?š䱭3nGtO@ B56FdI+ZfJ0Eqrs  M2] %Τ4v(@<%U ]ZXXTCcΙ h\U0&Sv.?gVMQѠA TJ~#צEud ~gt5a.N0GR̚ F MH@2h q|%b|;.ľ"OBD$LU|A]TdJx2%Kq%] *+*#F 95h>Y_[.aaKϰHu'S都ѱOMo /($/BDPY 6N2gq+ }Ϟپ:\Yv%coCb^tm.R{lTKf,'!qq֌i4}P\vk@ $?<QsYdŀϛUA^P2ѥELYE*$*ܕt0w1#C,!i!đ;t M Ē\OXg*yjqJ`mu}h:ߎ]$Fj|4ոG]7=4R H֯\]nvm[1&KTh'eyrYA5ic%B mm_%7vX/N@OB:g˨9  HSG(kǕK7Mms:t aUzH2=:5SPXJJ*aa6=SD>]zdCDLKR2M}1eMeQ`({/8U2}hފL։qêhW;pE"P YF,WcƢt1nm\O b'GMJ{&ͱT9*d'~~{wf8p4J!"umJhʺR!ȡ rGRӃ3ԔhRҊ+k#W 7КDzX}mĀv12p_^_/ՠ֘j0ԮnOG^ Q:gD3Q)B? nD:eD6S5ј$aņ02cR?ȡ @*VG®s,ŗilUt-AM"I+cBCTRF}YE_FU8KHw,5w!gtZ;/| {r'nk󩨅)&Ĕl1dV p;'wx0PXv_>KCHMKC5ٳ9/޿>'Q>kuNPˡS!ȡDT)s>yt+瞿צtGfK~q}OXfἪDRW,~ ʬ7W1DƑvdb9&q/I0M 3;|YƨzɼtOQ295ED14V\M>sKSoV7 b^eredY?ww~_T4s_r)s)cDnROُ'*-6FŕN7_x敃͛"YPyY€ꁁ0Hhbܿޣ{g쪮с:*nSC(Ŵ6UU nwc+)>!@!5!6a;/st[?/ûf~4+?Xp]T"LJk_ZXׂPR!̡Դ HSUqS*&%qډFY3/k\#)@Tl +(ҋj"&avF I jq(Va+!Υ2LL;ozN^_w>kT#Bx I)H%^38?>LfΏW_;mF&@_kX4G0Fޠe9f9%B4]Bbzl 9+ˑs-Oj[QRSǥxJ m4'M1 څg=7W4(S^X9rLzK+UBcW(Ȋ΃L@)h $U5s9Ї681┍IA٬ ;IɷU]U` ~6Wymgݸ!Ds8n1lf-rҶ/|^z{5˛_R}JAQt)R%#Y@9aފ9ksm[*הFtG~fwU%dUӹviu^ST%;#{C=MR TڎՆ m_.#>=+1R }!^00'L ZI&,=M*Fa]Ê 1AJV\H.ID1B5\q3pTvbœ-[ӂ7Բ["TawQ\\U%)#F;@yĘzcu= 9z͟[74N}!nvg̫?[B6RVVJA} eQ!)ЊЄХAU%u{g{Mxٹ:!S+4Y¥BΉb&D3k<(Gr&|f/|A; eĨQMl0R 6B'̅(eRD"$CJ D&iJI*2 lKuU(cT2P5&㔩1Z[R0>)_K=NQl%eW(ʉm*"ָR{RU) .B )]i?ՁP:LJ\sPqY&R,<ʊB]6)aƝǃ'GG9^`S*e| ).MC+!4]dTjjQKqkt?\=*#s_=Q{0R:_GΞk59'OvEp-БF`\@br1Xk9&%DJh|WJZ2TIlqZJ#SZl- "jH'PS_G>]_Qs&`CAj8`ojX*L:"S#]o=+ZUe!̷)1gߺߕ.URNVhfCQiWڬMӃG{n}\8v֍&(S4̹ >prJGB) :ͬBwM.]6"\:D]2VWJBRuds{\&yhL=DCӥfD Z\69O0W=/d!w 6]  j1mc Y7BS PO@q{Y,ib5rQ8vyj X3Ź129i% /> ͚.? dVʬV9.|3|~OycATv=o8 f`!$>}_+rx;'¾UYIe*.UJ $edQq.s96=]r5"=;:JCoa3X*9)`ᨫ(h#*}1J`a JTkm?mjcLSFzu,zI`AzBF?kcb ]䳟]Ck6J2*Bn .Y) MI AoũWMO@ErrBf[Z vޅOn6®I5`bSHx*R!iE#M ;yaQ!.) T h%L$$?]Gpd M|یI` ɷ`h \AJQq Te:DiTyJIV`OF#TӖU"pFK9'*?#M/T:Jg袩7oqHQA>gt8${LU'gzxȄ0S"'8HEMȷƊ@AUظrk*e~1br%Q'Υ?B9;"ZѳirF b9੭<UeF=ӼN-guGnUWoȥ9 K^ GfwG6ϟt)`kt`sfP[M93]<7>B^ȫȨS!Kwsw޾N{(0w>y|d-Gr-b' M &1@EצrJB1ħJؐgFm* LB ㇓3Rۤ4-phPSVDkK0ޤ\B¿ul*N*ʢ)K~UdnHlEKbvd iJCfl?1_Xw<ő3r-10>醣پG'V~boTz/\Lđ>䗬x[Dw_[Qͷ>:}t |c/Lt<>zh{ǓҌJ'r4ʈw(,J5mbBR+UAZrUB]LX"c3nU$&H\V(YTone*]?CJ)&#9ʥttZZ_sdGPLMjcz >u|9q%- KU5 qM÷qWNRH>bjZaĖp{{͗μVpBH16ۥ.y認${r_*Y/8TxdzpKmR$CJMՕz0YJKc 1rb b' Jd4K 2SGPLhhcrO0rP,4R( E1Y|9:TJ>7A#$}]'l:aVhW岆bFEՒ`R԰ׯOaM+1Im|2/^&N<1GA}b>k:p p[->;1eT9/b;}ڝ޺U^suuL.&x#LmGbGi(ghܝda\D#cKfр2 (pTƙ٪evLV2Clذ|Nf.urÚOmJagFsQ)ml d ~現fQ h4ŮdYB姶v9{ ;o\Oߛh5z~h'ZqnԃʮYcaa`")yz*}"wJTVB"2\\-A厝r[Ҷڒ6h+4⿦o[OOm#1PZad!2PH%_.1\f>UjDw2]R_^,X<#?%BSaC&=mu~B ƚ=緾>0[-شmSy4m4 kS:^[$76M_z5N%[Cr湟feo=`*Z^E2({Ǵ!t Q;<<0CUM`n>jVʹRig55n70w/^^9Ire SBd1%IWX.Y̎gE ׎ R=\?gA>6 C Mldv]v&Ő2su`msDF G6ޅuH75:R\+'ԡrN 行Ƽe'lb5HպIOWwGn$m#{\o½?3?mO!Z;?sόGϧjXϜvŵ}upTEF97{?7& dgvvy~g=`0vf`U` ~NVDV y!WMrਗmCD.}%GOrSo 1'׿v%mT-ߍG! 'ɉe^j<}<,K7]ĮK 'Ds ֡EV̴tLևut#w J3 ete>*)%wiz'EX5o2 tzuJE,|0}]ot9]iL@ |% Y_pRFAbK7tX ]VF[[wzܫrvC zWk;ɢCM|fab))U5*WmˍLȎ/=Zyߌ?o޾Io~W}OF)%Z\'! ({Z+%f [Brbr_{Τ#G#T6*W*e*kO[P%OV1Bz?R/'Uj)zˏ1+jhk̳ٓi; 9WG?rYu!q5M}8=9_] q3߼t5R9;vo;in]*BLOGG0Mz`ucue?6sNpCK`IJq<\\]Qx9$rfu&E$V csR+;.&[-?<|4{iQBo$J̊lw[t~;\ ޕŒ9 O9 E!҃#n)&FfYk#ܲgr]9"Tg/^κHƅ ʿ]T9{O̲E5nj4Hg y8Ǔk}h{CjĔɣṋf~qGG7M0/jIXdʝF${AFWVpJ؄ɣ2WnxC";CC #hZL8?h>Z 2g9`妋VQ $k=Z=O֟ۖa5Ϲw_Vݒ!Fb2A 16@R)LNSe8bR+)R`C,`,HI[-ݯtߝϰ5}+yKz4z޳koh׋I%:+uwS+Wo_{7/V'~rzs$Q&"sY%a[ʅ6m~v90({ A;f̓eH>22260Ic\Vz%rArs\!lbPTo۾W>XkCSx}!(<~moz 6ݗmSDTTIHr />lmt:ilur:*"9W4މ\lo/(qS]OFN 1G\((;Y$D{拾? xI'vu31I^6?ԈFxQ? y k)jbB~G].˭xD1)R=*^:L G|! ɗ\Y "'ehs#c! nusՎu+7InͦqFm7;p]HO=ؿRB"Ꮋ/A)}d̸%wT ]FS|FՏ~xCU- q^i5ٚ:EJ]6ZV6dB*{WW흗?sOl=񗱾$"c4ީ_Dػ&wŇux=򟊳C%-W_|oic!\ZxO[ syɅRΎ DGi0QX~LԵ PŲhqF^ʋE-!Эl#s6'eھPTudnW'/<}ouZ+aB}Ky[A ~eW7orͳxYS>D2nJɺR(vARզGv>txM"6v+;?^ܺrѦZs%!H^OÐF:Nh?fŤy Tyx׸ jߚC]LJmѧ桁vX y,Qcs!wC<>*\|?=14̯]kfn4ZNafe;n| _1N狟ӟ~{գ;זi%kkﭥq)ͻ^t7 iL eTk`>fuS/2!QY!p<9ǾRho=!Y4[BI%B(u\lo5'6o^/aȔ:)Mg<~!0UBOۇy@ɘN^2.JcC9!b6D;; )3̠$bT4+l*sOE h #_ԝŽ`pN&;2MUzVj88^J$^`s t;?w?3ozs/?wᙃ?W?c pdgT(֍T\Hm(Znw'^彈DJ j.\O N `ܶ3Ň!}>'Y;Zg`6 W"G@-8+Ui[y :Yq|_Nvlm\XJE]eb=9@Oq>Bn09d51fK"٘YL&MD1I&4d%2&*%sam>P!B.ìدy[WiZx^zlW 6\Ove; E@G*DAa! (e5Az;'0|bRGR.HcB]~ړej-.=)LAsܜTMzxogNlJ֧׸lʟ_z]}?ҋCׯלE7vG{UJU.{%fRo_ǿ_{Ƒ dhl17'NH䐱l6x|s#T> AK57,όnJTзy)K B>0]dxğ/Ĵx]hqݫ*R|.w+W_v٭"Sj %;0"^RujJ$h 6jMW0fj07-!Eo<ֶ+ߵC7m-Q%AruzW>q~֕H֪}orkzsIH/nxsXYN>?s];'-n}⣏^{ P\G˝Xyk -9΂y5AbޒRu~? U^tEY3!Ї }S|^:uфS %$E?(Q윂À/|\.-Ob\FrQx9eS%3J;om:j{g_ur-[! Q%ba|II˰O&V0X( jX>!VЄC_47tqh>:OaV~h:xxĕUy@U{|էvwՠW︻}ů;9I/_Us] |ѳȿW8|߷Ө_?z[}$ .:Ȑǿ kM/hVW;G۟kU.ڮGýJEd vSD*" Jw] @ȈJ5Y5u]f[C.]J[qvz:`okcBgCrWv?k:zV`f(@Zz *pq!B",d j_!vXM&3h {{u_xۦ#ؓ۫n[| !%* Wޚ7w,ڷw˶S,^N} ~9|Wo3? b `x>Kҳw~7,ђ0ph]X2Ed%Gb%L]^Q URoPi\z ?êdØ,>vgccٍ,=>' ) Vw'<\~/D"$%0&rj\"Eй)RhH .ѓ(˾gìV㊘%P}goz*#O1]|_+{1.>NqF<4²^ >+xe4d[O2!)?u+ Xe)QlYTdYRf"XZ!m~=@aq\*Qչ-/XM F};>ǢNqzN~7eK݆ rǤo}>7n.NVnb}FW[4ӨZIS #JA)/O<=eQdIR0r)PpDZTTB`X(b8ݟUvV.gsͦ{|O>/ѡza#/݅{[?`Gk{ -obQ'֛C6)&CH bX#7<(-M}u*a%8l: BH|8HWx[ ;@.$ȩR+{׵2ny^_Igݏ_P/,*:ճn=;Z.p\J2F7u wVڊ$[  Q>yDYG hsJ 1ƍHKbcC_?)IqY99͉\]~+'^3,<.͠OBlcVӥl!x)Y]%1򵈉.`RØAƿVY hc1ygCݙt-b:oh[gKz ~ lr^F?lˆ* 3kH%OGG;Jcmo{^gͫg$px󧗮$<[.O|{]- 2ژ2 MMHl*"4E2+I,C$KaI3l{I乜d0dJʢ*Y,I}Arv`ե)^C3j[CM ps۵RLܾΏ*!=  xOjv g%]Pe4f 9cmTZeӗ{zG kU51Zcɽ˻ףoޘ^/ϔjDec/n00O* ժ_-|7_ sΏV| kZ*vfTe@IF֨[`% ]ޥ(!כ!*d`ؘ4Fn`-Ct$L|Ռ~i6%(Gx7Y"٪qgpexibtnVHqH\#ƣCՋTT+ױ O+˕iOw^'Oʅߣ( ;1a=eeJ'`|iLb+X"8 T ?\qFg9~Xw<Y܋"h3]~/aw?s.ș܉6sO&u})F.[D:RT}kq30"FƮ29V*H Ai@K&H+@F'd8r.c~%Td.C# 7Y.]t;r5E g.%D!7{?ڕ=yަoRB@dJ|ҍ~,-i<O'$QNbUml|>F кaBc-!E}t!'(`B[M a^k^٧rSTix>{D\F܆{v#ny3gޙW9^G"0EDFbaΦ(a!Hׁ,R8Q ,cmPT$Fx$/ !BV=GR)zk!󜤢g(ؔn&Sdoh9 'Qy+@|a)S*Z<̝eV`N?"P))g|IB0*:w)xk0Bp.a|+Q5<>m+6WؑRS Z-IPhK1F}.ŗlvNy%cj *Td<¿݂o2#H(oP)$HdePWZCS1pcF.e}*|`m놅mt} >)Ҁb)^UkE)m4YJ1m!EuoI87OՒ"\X6=ID19ZnzEw aɳ3%tT!n.clyZ}ҖzOJ|( 4+rRjh&< JOC+{i5Nϖٕ9HH>7+Ckm]w1X!Vִ2zjJKP'rg晁"R e{Sr6OanÐ#ΥWn|Ԟy%G9R쨋x A20$1(p9TJW|̡FFU5%Yv{Đ;NZ$8yRd15@*8O DR(jןYCLuUfG?yLb,{10B_ݳ-cŰz ;QHŵ8jNܩcnA]hQ1@ 'kپC`tQVa!8.-79 @M*e+!xf9|Ƈ;Wqg]4|d2?޿c(>}'EvT>R%P%bZ~)!mnF|nIӡsN#}i^U(u@4ȇ: ^Ӹ(8RwdҨg q:PJg+kViTitiu|rx:OXg6K`C1wf\+SzB3IKTdkosxnokSa??u6B~: kT@Tj#!D\N|PM棠#/5;XǦ^(b!>AYE+/RB)ǒy}g-rJzduV!it 12G! П-kpya'\͔pAʵvY\6J5ViĈ/ @kE xkIFCvͶeN@"UJR{/ V[ݒlTm/-J!\  HLEɗ('T)y\OoWW\}{a8yjFIUY'b5ZUt3y$p@c0@?GP؍]z1"Xr27„KqGP\$JG h06E}/R0>lS09,s%V۫')@ZC.D%%5|Pur,E$W]Meй1]ːM/d$b93PI8kW}DIjT èq]W2@BB5tgZ=A41NB(@:5RUo::ѽ rTC-fsȼH G'3(#-,N0ߝR.sCP=jJΤT^ J&\KebZkp9'ʲa|G69?nHx|lW6`T]>&6V8^BbS1)&Fݯ'LpSJ(jGox-?b2mXQL'uKIG}q~/\=C]ウP>5WjTMʹ%W\ (h:ijU\`QNr;x)8C9: C> Fkf lG\H1KPoCGR7HrW0?X\^Tqf5l3G`K ~HAQ䝗3L+Yy4BQ"úFݧvX,Vz&W *|D2Y062>)Ni-f&g&;yZUFIUA5Ns/u?~`9Ar7؇NǕM.4*5@Cko3fRȜTEno#kZPb`SdR!-!9¥b\#yu\E$37XY&`J i0?979|#T. D*$(4jpt5@}Q(Ou)`2y+I`OƲ;sA|I7X'Bȷ^JYMzkOuIl"5hi`(h-ٚ-? 9$,f"t9#Dm/̌]FA3E<0ۏuHuTnC& =HPPFs`棂\S)x"rMC@uE F8I6"cчhJ^sO=&/DG&(`EؐV j {l[!^K B(Dž}r[ݰEWkވG"w [1/_RZi]M z 쫆$9k`%*>JsG*G~oM TfZdSs1(#4ƘX3t@R S%)BγD5)к"*<RdU{JuYڻ*xwVIK[ިUKt+ey@m-0{=քk X'@9W% Tl]jZ4de,j au ֻBR*:iY{6tqolH1 ZZKI(AZpG1nr!M񌅁EЍ'>XJFNBa 'F+n BZ BEԠP̧Ͽ'H$%+C@U岕 ja:чQA{ae'q!xvPBTgHG#%"A6I rƵ3)Tl7-D B]bVN BT!$2JTL*% o$&V9)g7P||.n^!ǧ  }mDT$XI@Y$B$a| }+]ulP}mWfR&[綠AEKHQhI\(::[/V>`$SMZ`l82v0\wU8 |B(DTpREeʈԼ] !4Y+J] \Q`(ep_v:?I`42oHZD-l Q8i0h'2䤫HK ~VcnΉ(e-[YB$2jtIDg8%(&D$E?0")|Ȅ-Tԁ =g\!a< Ě،F\#]Uܽ61(-ILe=/aci3‡?o$8"hY-?X@`(I0y \ܛ\|t@ɤSDpS6uduL Z1R )Vh0yb z<ڠ) &A$7S֨$:b(e%RD2(L<+Ux[יl\E5I#a4.c> "J/#XVb/;W)bP֧|FiCyʥhlh(ʼn:_IGwbA)R Eۮ_e߯zT|}] L:Zuq|[Foųs4N(4,Bp$QJs'G׷.>qEgVߚ|1Iben$(',rZ$J2Ñʿ>%pl #c3]IxTJ⋇]s 2SCƬ*yA$ `K6]+ß{Qۉ!w9 jzuTK]kS1ȩVF XR}RP |r^bIo$Ä#C6Js3J*F`"!$P}>k>lHxtf$ʳq:󀓐h,&FR5YarZa?ܷ΅hǬFzxĜ,`$-N݅i0-dnC= Qb6D@4l!hm c~?Xl-IKRڱD8T+9Ub UE&c$tNjb&FOj"M) ?/Yc>Qx@pW L9=JZiGۊ /Kp(\1{ :`3NCZC\&u=\9v7"2[-5`񳟼O IUq?H佑Y=6P 2#n9q_`T1e Ib_d{+/r+5| f!O쾏JKN!c8GZۿ駼}꠻v{}o/?T Kcg^.y[@=)kwID7\dĸ?hH/%/˺+RpLPD% 6.Bl˰0,:L4q"B)2lziUO8E?70+`R!0L<XSJ9!2!]Og&@<3 ;dg./VEI/rJ}3H?NLx2 ǯ?O&k1:)ot/rM^)v>]+o2\2k6eN93%O.KN-‹ax2S *1y=KI/d6wCH}~*_/Go| űۍ7(-^l cK^ rff\.#rִ)_o#Ĵ2lHݟ_B/%1-6N 3ȦT"^l  CplZyvsS,~bTt'bHm5.ǛBC󙀈5Am^ unc">pČ/ORa}Ɵ,[8i:} nȡ]aG=V/(-|eZ@1szS"Aʜ6eu!-+G(3+^ZoɐxYV^|KZ%`3% !/i5J|o80d4Sڂ;<4QX!=#Ґbtk^j]fZ9l*]HiRS@vegε1-[))nT2 U>IblvdS3"H%sGMU,%L=CNYm™hLc`d q psx6 bCUh[ydnY K4J{ZD)[BpW`N ᳶ(wD,FFLy?9L2311ލ;{iNm!}2F= 0Ω`d.uZ3pblcvHJ"P.+kyP$ J^UM׆!gGbzd iP̓abQ2|AQCJZo{}VéOp,qEjH~:!%RƕbC2׽Ҫ26a욐ZU`?ldCE+Dg8d9vvo ޻RQ>Y!:͞;1=z"ӴD 7n]!r8yLy $7[2*uZ@ P"kļ(/1peOAD)l5$[:3Ls/=pȁMf, bּkk}=^Je[PMS!b ƌ9 SOu1KU4g™Ąz*d~j>o c c 7QDv&ׂ-': >РyZ8mjyrWΓ,Чod$od`hYiPq3dQ)С{*.)G+QEFRҡN8cY{d}*O. 2ϫI~uVʽv+{mJuM-# xKao 9a Ȯ)cx- #^gA%G$5V1#gou\{VU01hwn,㜩Gִ0}9vDZ{O9o 50~uL6!y- O+OtΗq̰^r5sKِ}&2udЎ.Jx]2UytY-dz1aiIdMTvѮ5LX*4JDM x{8cx])lnf@(u5C]ۭ ',tor:L SlJCacqPL=ծ\%Ǩ>Vï&XrjM!`Du69%B1XIҘH7BDZ{^oVVB+yh{ sSXp$uMc&\2tɴl\yɠlPRmzH4c n(D@Ԙc#a,D)abn^dSzOw6mޟ7|7-=srLLL[3zRp)% At#C'y`~&7Fʎ{ Kk#.@A%&F%Ch`=8ď br&* "ZZyrr|ݏף~ rJ7lNeW]2}]׶`ė//іӲx\ Ĕ4cnm 2Ďa1)*/ⱦ9og$x˧.΃c_cU{r^y\f#no7{up|Am6iOM/ lAfhc03 O<@SMG'b#=zkL,Cl:š qCB hF)E}̑%܀vDzVDnRnRz[o/ZU9;zJV=68Бaœ/B)a1%k-ptM `A*c7$;מ,~bMZm2Db7]8]K>dϢ$=4!Cc@//\{Wռ u<%DgQV葷:ϐʞW祑 c]y&84&:cgؐxDx U}Uڔ{OKڵkﳄ6UfB hѷ8ə%{=ƒqڙ3! g#ݿSTXb:kqC(Ǔ7$5!eOȃ܄⼖mjRRn~{voRECl8MzeisR+q=1.lc?a3l"ZWHvyWȉB{t“$uw8:ǶR۩h^ <$KnrOÙ|6'}׌")Q_ot]BU్f<>c1ŏyB۫7-iіzGU)@W1GXE1KU)f%JKlv rnrA@ Q[+P9zKRַE]eX¦8v7ɯO^O*QdJ݆RjBʐ*+>%bCל#Ո:=GSj:`4: UJ@It|e5L hU qH$D6+GE1 B77ذcupZ<1G#R7b饇90-|Cud ɟƭu/?ҋZZi{+mzı~ i98-pV8-eʛnj)'Nz$jDLYfH^]Dl8x%41 l:I(2[)̌7JS*ҴIENDB`gift-0.2.0/testdata/dst_unsharp_mask.png000066400000000000000000001157361513354670200203510ustar00rootroot00000000000000PNG  IHDRxԅOIDATxq! ;o\8y9onLF;׶Ń|p]&E%0.r& )1%'Q"bRE"J5fT{jgFDF$BV$uLޭ쮬nWNzOLf&A²}Z#Ō)!v^Ցe$MN v@U=0;$Tp^ |:I,?,0A_͟}{q6Zj9z3ׯx1~:w'/o}67'շރ&%-f ki4l@菿(_o־.J\]?4|f͹-nW 6W9.>ɧ/?xr:;9C')F_;}y8x9fE P%E@DќDS #FO-Kpe$!!G sc_1- ȶ3^tx4{wTA.,<9#śGb!X9 %AD@’Ko#l1C *e-c נgqm}4;M/<>= 4WxmCPo 4N oޛ'v/zq{2OY;GOcV\`[;,6v/<{v1$4u ɾ=72%ώ9]Ja8VVSgyq4amp̌YT/;75v7|{hl*BG@ED@V#A*^52#(!Ec &d"*&T v<;lt Pu]O?~v0aMDA_;͢ =CcGbo2pVp1(8 <9FUp$5E&Frh(pz0`>}rzUnLǞ(q*L|oo7_[.7Zly9{>}n8;8؟.+"Ͷ+1 "nN9)",8+z6޼xymg7Ԯӓ^58jT|~p|{kM֯xq鋧PP0"(b͹cVSG$!Z#ABy&q>rSUlGMx1^KNvK_you}}z2c1X[רX7„&X*b,*Ũ 58p)hdž $GI+)(4*O(&-w<P@ L.-}έj-vd'Շs~ׯ?ov:8NDFuVB]QЋjW WMa3i걣m\uW.S?zِDNf ãO\;o?Zp@|aբ1XĔ$]%f8`( L{6WTtC$ӐF]hЗ_j#cyyeexԶgYK6a# 弔EjUgH@$Pn&-8?96TF'C# CV @d&%h؛R/}~6ٝ[ᾪC٢_ѣWx:_o{/)Ƒ>qT.Akl& Foۤ-qbO-{ |+nq;-ǠN3p0.#qLs?;xap#W(Ƈ5acTVpYY#? F5u몮r\ Ɯ,/3a jɌ\o޳~71wqJѳ ζQ#yrc3PL}ͨ xfa)URC NscYr!8yqsz<챐:g~śO/jv2Iof2'[w}|gt`R=Օ#2 p6zݝ7.m'NT+a6w׮V/^5sp4 nJuY:;@O_d«[߼ϧ:c7 `af)R-AD5?BևP$ 9P X@6Щ +ۃa l' جK\!v);.Q}Ѵ¾"B((K` AP d" YeƜK(=$U̕$EhqcSyWLJ}'_k/_@f`Z8`Jʸnҥ?w_3޺ZuqC7 ٣$PBA{@fИ5](uO3Wk++K.&n&i^yw0\wG^pF}:AX,gQ7=Fds4pe|=p8p2׫Z0%T! PPՍ#.βTU0$~+H o\}dHw?~jca| dAg^ }YPj3la31!`(rqYLRPd ExWzf-`-&ty:'a׫z8dFLs6r}ͺĕsmdBRDT%Ėsb/hQԟͺãgOk+ƫWv+oLbO&|<;=?Oʈ =9ھ{~ѣ?^TVŞՍ P]U uS F#?+u#+!^gd8]\ՠ.*؇AUUUSxXy՜Q`cgdv|7f r̈@.bȈ resd̝h#&IiQp:n,sTE{n8Hhξ'-sbǥ04=-HKG}jOXy/3u8+Է2BuX  0][9faЌUAg H0ǘ!%5gA{vÝ+.]>ß|c0L8TҒJa4kM.Y6\ԃ ƔCQO}!,R+V]@׫E 8er,Ug3ޙ0} ;/8<{~~[LbIY 5Ư [w@mrO1Sxڃ昔14KW' KU DPp燽$f43MWYdi!u4.ZƔQtڟEѨt<;֠O]χúV/(j L'dc<^XI UQ)1sjٚAʙY.#(ymsuxc/~zg_ډY$` E#Zfj#{DPPXTHM%9%T`8(sc&DJYsC(ࡔ<:xxp{!E7b}+_|O޹}۶&rҬ".Mֶ>`ʼnR!Ԝ]e1S Sf4%{;a{Iz;hsxrr/y)3]ۓ'v1_t"WЬB=PC xҁ ͨBg]ZD\vQU?vNΟ]aǺ94eTee$j7г8 'a;GB+;_}OXj/Fw ^4&+LI%Ŝ%0`GP,EF@֟U1 c!*TAW _V5at\1CJu{o.хꓟ";7feLn١0{GSG)eWPX-;%,A/lpt 1y6w.4_r-Ɯ6l@Hil|HܟustP`KWp||baBFWեkώ$Ar쎧oͥ.,~RBǨؤ"#J8;6_17wj]|oyGyJ`&%ojjq"O%ddTl_Du"=NzPJ"YDѳ":r&_du 1- $^D2hq[g݋Y33%Xt5m(>-o)-6ȅBƗv/hL9 AؗN@٭6#Ѫ4ҴA51vkԑǖ>U06J+ xgw{lsED%]q) 2@13,+0)At=ŕҌBRT(R)Ŭk]9^2A窲H g XkfqKّ,s/,pDtcc懏]΅tp\ɺ+-%<~X燏8+ת+@T^Vf,CR_JrQAf5;[ܯm^x-^Qm6g`)r,ʠ8tCZzOLhT Z8b.!sU5ʜI!F{Cf t7t~.!Nj1@ cՕ9И3f0 EƥC.lĜfrHTɠD\AVؤ2PKN&& apw舂Śe+_19 f`-܇}x۟<|غqxm.'nc{u+*i9fǧl% |o]{˲]` l" D9@M%d KɋP|4!||SѮc[;DBRUkEN`637^r󕷾o sCM]k yۧvksS9Qi+0x5r/Xܚ+%;5||).`6*09 /dȊGA gcܕ$'-^I^F%U7qvΒ@f\3qrd*}Y/LB3E} CaO-767ַ.쫎UTg諺V~}tƺ3zz$lI&j:T(iuqm:aS Ǖ?;=t$bG]tdsť Fh<<jIjjs=&5ggg w>~]!z=78`1¥Y3$mi7*p\B$hFRk9w/ABKLdPއ:G bWPJq7g:oʠޣ)jsJ#dTf歝_9{r?ٓr8M{{L3,7Kp<~sW6/^̴'5B3L59oJ+(,&K5ƨc2h̋ĥX.%YA,D=Cjb`/c"&r*rݚeb|zN~>Woόm3f˜C0]z)"]կ _̏wW{o\|ʕ7t3Aji7 ˬ -10cJ)N5fGUѣoپ~w Iu=,&T5d\ZƄf P5kNsr֬[W_M9c(5C~o9xM=csgV9waSȍ&[ӽ++ H]Vs$TLz2IHL)*"p jpYs@)M*dWuBu](CԄ\.-)JPye N"jXz%WՀLB"N_\]}}\_dp+_OMNR8AB+StX5sGp|=\ 2sD˖_[Gh2WA3qTzrg;|{_/fiu\zhf REG@=Hr)MQ.-6/4>ߛ="3|-%/h!9G[ͶIfATBJ(IR$ބK=w UPUԆc(%η2Iˀ(3^t4ē֖: ׆kjkP4c/6ڕw:[tacwg'{$}\1us m(c%/|8>>{O_)f%U6/b: r4X41yʫ`F%)R;zWldjӣg~t/^@sΨtZeؖXˉS>Ƕ$Ds%VI]?P1Ko5_u9BDS U\M7/4i ('A0rQH]E5|EU1!v{R?q2`24i]RR)[,"l@B;6m##Ǿi(x݌+Kο?2`(X‚[+.* 9U|/ݸ 67~MWVms2'M"&в%?Jw =fvޔ@0AgOL_2bij SRMYL0_NRj(E ޡՍt4jsMQJ#)Z^ 7VI>`M=?nr/žE^p7hǥ2ÓRfZ6Sxg9mi;Wjtֵ뾞&AYsJ4SĬ6yH sfׁIt2&^S;pPmSeqx DMA-qpR*fT&L;%ζ9!cu3QT NI `%r3mą{C 1`AP(ӴJG5i t5$2Tm|%ِyҵ`" !T)qERňLtĮ(4j`Jْ1a$ȘL*h!+ptrQ+R2F  Ɔ@Pz,P\Ѳ`4;h NVW6^~zo:y3r`"m0jm~`Ǐ+?.bWbqv\ŃI"v zG" `pm ,ú..UhYmgO?ykkFkSr*QbKf3V;`.b`6ƈJ psaeȘLYTSJ<6U?lV+ώNd~d},s>"+k̽$Ee:K@řʠ{9`,d&K\iO Ä٬-3Nf;ؕw6c DMѤU2(ɱмfI u\eC9^4 xR tu/}'ͭ[ UR~ͫ/7O|ЌOyJƜDsL]9/~)IAU生>z$/]}׹hҼKd%6J7 bUSe1$\ (rG_2W(EjteTOrk<&#Lhdle.eSPDMџK5!UTx*OyρC(qb(ty7X{9yr̳DX(#wȴG=;?sU;~[\.`$p:KҼk~\&NK[YϏǃ,gJu* 7߿~v"]smrJbpD*I}߽x?fq2l6vꦌ8*5sVXzBA S-žM>f}-,tQH$Hd g"h9^7au}S}ݞUXNE㓎N/v5_u30BUW>4MSWcfŕ`#>q IL=ZRQ4Hrj޴(7 tJb,gQ?/ehoh4ӃϾz\ar&PmS(8Qr^4owJ?ɯ4ZCųgϞ\փ+l1M6|ťSصI7f4gG''ϟ>oޘx1?~c7 C j)9=Í5˪SJYƇʛrwo_rN>|zz~h8t>.h[㭥\ζJU-9>3ͺ<}c^1Y@%JҶ'.Mqe%_k_S}.@x0շ[2m7ڀD5QN}B/nQU)Am 狃g9M0 a4+K)^4<1.AHIS,%"]]RYUS UJB[=e{r%f:;}ڕϲXC.-HYP[17^K!vڥ`c+OJ"}'y'PRm^re1E -/(I[ILmr{z891W]KKGH USR}?>=>tezѧjrwF=( Q_CBݟ>XVg E慠?5`նOU9EGTzf-NMO9`e،sT * ڎ@2^}}Dnbye9.) m<_NNA!n@>xcZ@9d"R(F̐rZCW@7\v%Kב9цE^I)3ՉRNbM1[̈1 H껴+f?k'C;D~^5+Ƥ[_PÃ} MF|ͼo|ӓlrۿߝf1MNLV :'>4ǟ|lXĵ|T":s'Ӄӓg;o`0URtn<_Z"H> 2$9F$Cm᜚z0]*-uBiq]9xn3)jMx/5&sۈ[c\06@E-!2<6K7TixͰIƗ^::A%I)[dslB˴}EEi@1@NQQlm{Cfrp8݅g}o '# Ibzl_3mLiU팫E` ~z|~}j<nL,;?ML!Ll{}򵫗.^2 ѹ.ܑ t;х̻8Lghܬ4,вU"N :HαJ*~S D}֒ˑ,) %bjNTŢx +`Ej gO,?P6SPf9DcNQFRĹLfED$3_yWcX7텖9]#ҭۋ>Kܨ\e0vq"-䴊q&.ľIr-N\nep>U@څ*k ,B,JϒʤYreTŒ%-G ʩ.K$HeLhlZ{wYpWkZ,jJrM?};FIs h{uы00IS\8X+^d|! kk6և͵VUOl+>VV6&[kka2qPcjj߈h\+r׍%+ bSu0;i*vޣ/CIy"u Bj\=t\=(j\Jxr{J25):ʘ X",WM(z%,|1E&B̶>Y,+Xl,KP&tD\T.KAGYZX.Ա/ L{+}Wضm}dS}rmT7nEJ}'R1}^n^_8,b6?g?ƥw6r4C nݙ k˻OGBt*$,WeUI~tk[/;xm:YL]czuJRSS+9F2Ii28W>P2{G%Jh0`ˮW^\^֦XP)X2,K1%2[OZΈ``y0%-R*Wї/]y-7,-+:.4]SOTTr6٪5M*T+oT񐜤W+KDXt xvo%ic&sYrR\tֻ.E;ޕNϪjgm0lVϦ'"]ʋil}'j,Or_.iKK,py>8]q k.2Q;AY`u}9hj]K);C,b,!Pig5L-EYBE]hHƾ EYѬ}mYJ i6Ŵfͨ%,a ,mʜ12׾jyvVXs? F;O9 ᷾5bd s_>};o%K\΂"6V:EshRTx8Mɹ ZkpU-VZ,]bGA(GtӫRjY'_~lч hK]dK@@cfӄeL5!LW+'#A֓rLZ[ Kq2ҁ BE_`ɜZRրR2/ jL/WjtsMlu ks7LͲ,F,cmlcc<\ ]Q 4tEMTCt4j0P)`[5[Je*s|wsΞ!B{{[c_CBdN1At/P#妲;{pD M/>|  l&j}jm/|TZB۱+0X7>羪{q<,Z얺IJY5ȁ,3:E)h1B11& V QDU**̿i&,PeN!KvbI gQA]a xNj{ki4gƤ7ƧO>7R3csʊ3OoxǶx+o^QKfp}vsCx⪉ծvy,(;|9[vXBk@;NL1Şr$.i?˓^+JDiZPN4jEaǧ7^휮*v`~믜nz0fҏԹ( G )P 0 lѢĤ>PJeaprdJ1 儗WZCR,ٵd O:ģQ[/߼QL3׎>u`D]Ϟ޸ܙ>r be"X+/rVـ"K䣣j &M3u MS FH,I3o8TvqsviP)tJK䘼Rjsr\Yq$:ѬqA ʦ  J+J,ýĨ3KχDSkGNlַr>Us׿囿emo>xY OoF#W{7@6WR>l. #y lH%@VaA")Ҿ2XzFLBXHAvsdbD=]~,PIAґb*#sxc},U߭t`b (,k_HkzS.O:9}_zQ7]~fxS+߂RuUQF3j.]ҍ.UVB(qʙ4g}HUQhZ1u5\:x'0 XīPbFۍμ=,FY^VRn2Q %Ւ,0١OrFߺ+~MߺG tU?k^3w1ԯھq8<prQ[y3X^KRQqC)P*|"'( sr!#AR Lp .UI!99/r)HIQ]_{l}vmcתj n^YoLskK kMc}ؿzb/)S7W;FJ ^u'?o[@򍥱'']χ4*ej#76hNL doه>cA&iXVmqTs=З $=L£YgfdyVWWWO? c.Pw!P$?? 7io5?`rSGƻ?G.]0G̓o~ĞBrs>]P~y&YoxvicGٍVa7߷69Ķe/W})AKm?IСw!e:K|O VQ ]r!ۉ;~x4䓿3_,(%"iدyD|bQ1P rA!@%i,+c!6d^z`u߯u&JNpX7=;xx |ߏ{]9]Xc|#gc*O wFPQژ͙ B]EC YBS˦:T .!AŃFA1rMJY6J H`2XxJ:s)\uV;kBuԚ=*|4RJ#/W??LO~Ȇ {3mk(3/^:Lp}<"HNAa}VZ[? 21N Ih4BV'w?r/zn1~GID TQhvO왽idʤzݬczSDnb?1g_;6scB?LCjws3}ʳXۆ`~[F0?r^o_J mZ߰|JR}wpS=vԶ :Hqy1v݆ݿ6| + *l rk{ɩO~7}̥%UVd *klH j Q :Z@S0#<,e{ èm.$e(Pz+o &FTo4챠N=hm"p)X1jNB2 32 Y(q#C OAptLK*ؠ)LǾJ/>q1܌wryߩX>.U>AH"zcٙ[k>ۗ_L&\NFi-A#{2&J0o6|ڸ> _o)3SfykF0b%Y Pd _o;ϻH7F087d2;t8ù垽_J_8 la&am %V)>!6!J9D1rAAC odJ,"e5MꏄB{jJ9 lB d+Sh 1 0.|ۜ gd]:gn]@ڀK?zcX&+q:k3oG1̉?:*QaпB :AA42(oTM3wec6IQCUEYfJddqʧ靶3@[O$lx]oz7?d U@b{B [5x tU}ep;KU(,W~ե.cJr$_N%#s!eXXm@k4 ~c19\>2KEf 1>.6x}lcmTGcʄKힸgL.?;8zͫ ō_?9"]=^f|GGWp{mU]ZIre4&x~G?_.7R\FUrtr߻Xgx>b"A!3 YX }w}g{7]!K6)#JbD]й7`>r0Qv+Z-22nm.\|s`uM֤a0h TXCoK06>Ov/vޯqUL.F۱V+U VZ)])t9c N>_!wS߶[m}DžB, [TQY,lSv}ηKʳ7T+-TO·>b`1ͻnԊ;R4;̲ (ʿ[4*8(ŌT}6H?߯5L<`2 * H)klwLV*A5j]5CN@ Lkc/9ALӨZη~Փ_̢_y*Ԣ#= uI%x z `߽Z.Was؛"Q@Bj]mJ7v]BBѠ5QIsE_|sSaG:t<@LTLHe08̵jgoʜ<奥c(@r,UӔgww޲wn\%?}}?[翀c-- &dUiUUpv \sOC2.OG*W/cp1$<9T=4AUؔl+pې iZm˥^ui&F'U%]{+!kL:aMN}׷~/U=Y>."q!mޔFTعw}v.A8e7 )2*2Yh{ځqR="Q+(H*HHEeC,|rY,íaḧ́Yu'v 5CʉlnJU;v,Wz|q{ݒ}p, TӰ)ڈJYWЉ#:cRYf{#`ɲs0 ŗ|5L$CwRbp 7tTASWڽꎡnEiDE?8FS)Q.J}vrmK_[h$tkUЏmOBpp3L46f7u~~.ry-H+4k4lH$#^r$PJ( RF(%o *h@ n^YEȊc |-7Ѻ7Q߭W4KxfkCX*DNBy7y\z.عSя:?<|joފD.+X- ٕ@m%E}BD4TiЎЊDm$\ȑ%$JED,$DBm+Lw4I}Û}ܼ`칍w;vU`/ 9e@%Щ{1Wowzۛܓ_I_}j<2{ww߿-u :Z,s!Zcj&YhlTVP9Ǟ,"! Fl EY0PLV QF+q'B ZAh ™rZ,CFC+ Djؼ+mn<_2cG.^pB9VΈ"ҊEb&&X95>Xf5Td1>S Ȝ'i񌂜FLG$XQX:/"y@mX H`,Hoݼs7Nl;꠰7=0 '0vb\aT)c7y,B$UL h){$%ŒZt~{WY<829#5TR !箜Ύ<÷r1~F p0݅Hp |+~CȰ}~ hom~TH!9~Nܥ!Ǯ\Rf֙,uYθ<%qIqd(zhlm+Ʋe*B#+F9(| Ę2P:C6X1B)bTT4DByr X,ht_v*R:D+Y'o8].l/)=FP8ھ0x*S q(FV8ATWg"E$烪&[뻆NNTWb(WQ0FO(т\w)$;B ď()Uao!r A:u.#%Fp`/Qέ,)46E*UL⨧x/#oO2 {/w58IQV{/O)ԖYs%|@ ʷ.cVb2J&nŸ@fۭӀ֊wNLD˫W /)HNl FAfQ"iD=RF *@/6{eT v7͏ZƋzQI(RH; ih7~L[mAD}è6v_H]ng4)Z$䢀rɢhuc$`c`NŢ)i2ȔBj SˉcN%ʜYköf\d)XF忚~9\ul=m7,Prb`;zL.1gp8b H蚵 m\ً$i%6Y-*)D[U$%1`q0m 1|sEX<%Kl$6O 2 hÊ7?ٮIk=U4rZVR KI_ϮoݞPSϟXKzz-I\ʣYjD/%"R=SqhXt+u$=q,89JL1bCbJȤ!ߧ,N.}F*;@i ]ut< _:4`c F=ۼƕncHsթA;W>Z5m%fXu^?F<!Qm 2M!_ 3d8eD-KtIgDLe &72)ELZCoY's|OՇxWG}D-DRl @ą: *9vCj'ws8@_+}6r+H55Rك|H  ZmsV˚[)E8ڿ}̤BD y}Agֺ@ m"/L"C2P MՈ;M'Oo8|6 lSϜ).?椙(zµ-8+.lI6Y]5b TIHS _3\ZZ;5,˪9K(9R8:d:IQ`X=+!d#Pew~i;]ڹ8ʉ>u,~a4B0ɔ㘒kct+>%AehO#Z(IDn׽mE4PBcW_yִayrvs.e0Fˎؑ Bp!.eOoCd+*Wm h"W/QF 4"" p/L6tR_޷7^{OB]++?-חq(KFI>֡<ʜxyH*c.:,$@e.zn #sAZJb rl@G+[iˤ G6opO?_->x8nqZ$)AEiNntRb>ϢaqNf(h]vWP"x:S62́C۴$)E_KP8j\s6!_q-ܼcXus9J"q2ʸVfv#LCl1R!_xo3(BPp u=>YT->͐)"DMΠ5p+0( D L ,Y  Y5(RONJ('NAiK^唆4 lO1C*:a!AQЀ}o?x t{hP7m0˔`Q8r߮&#Quq3e?^+a:K#(": Gb=]RRzˣx1mU+ΗekEjR겓Zo7j(`owR9cU%okv^yOnռſ A3oGV>"lEUqAd LAF"p˗d*"('~IdE5q s)Z bsyHQ\kBb9W.HdHTrTOa LGp{y'^8>4F*ќDd?ƶ`H_&])YƼQ#dX< dPID$ N+ 8 PK>{kG9d=\V!DpmYhc.H+`%fOU㦚Φ7wnVnuݼ%0;;q6+V9iY"aL9g 'L i0.7IRaQ|*c|yPY,χ %#ĸSވHj+0>#ʜ4P$9 bE H%j[AhN5av/~㗟?;s G:M3HRao# p Jצz-YŕȥU52` XαII1e6()5Yo eS!h\ӆn\þc=E03dۤ{1>ikz"u4N"G1bc]}ZWו奩lInV+){F|N]g" =0" :2Z۪"!8y#zբhR@( Hϯo&(1JJ\rqT: ^^|5A3lOS* gdLq3y߇A[*w ]vw $-hT§hlˀ)۾'9S ){1g=/lznŶzwc7wZE s r6̨vf32k7FnRٺqk+4]F*,D+~F^.Gr 4VYp!!$()gXa(%()e(CjyT"!`Bg"ʡh%s46l+Jb9a9@)$QEppaQ\kvfW&p 5ع!I]NYHSJ|/G.qŔKH rR 5#D7n}LY}TTL$9rVVZ59Q5Ɋ\ͭ'Non(mn᳧MQ]5ַ;V9n.߸79fE?[0љS0JjmH&ʍ]B%iފc<[Nlj캜-0L)9 6XGcڪk ƈ,E`μs(Z oi1,3IDX`PP0LBm|B! IU5u֦xTa9ڌĦpDVUbdB:+ܨv҈B6HB[Ȫ)LYs(kZ4* R9AbU8~Ac_T†٠ ce@QMʪA.xP@t$LɆ BM=FTrV UTQ~DŠ $C|d݆T,Rۓttсp85lV)s >)ֺ.6e̝O<\kCA>$0cW1R]7i 66\qJR/s *QNgvAQa 0AU#hH 69jN"dd'TcTjY++C0UC+d J؉h#ʸ[Ne`B0QSJFu٬ge*'XK9ԡU*I ENCC*H d/ҠFڨ`q-H &{2MC]ddDe`pFXcE9,U2Z7{s򾮚Qe3Zlt3ٵUARw۰?Q}GU_meFr_Փ"lcb99LsSIJ)0Q01683T/Z%G1bR&`7H+HAG IwTN( ɠ`֒>`'$ݢ-nL)JgSN c#-e\6]-1UֺFU_B6p&Y|L70è@V@YTF4P2hh_gX]Ƙ 1*bjf 2b)GYD0V^MMD(%?֪o.hJ/7|(3BJ~)7^K >z YEH/KY`{.Xh1 K``%TVI:њtFSFM>ESuIdMg ?bQDֈ]o*DJF"kE;3PΫ= 4JBDT9,imI3/CL]JdcfShJ*rG1D8PIxT dV* X hR\"Ame9dGR|Q61U%J Z(%8ƯVfC^WJ[K OdGr\W>r]H'RRr8–Ej_3vWUf:P #̝̓'!ƕG"aH۾oə,p!NVjP7Q`ȩ ǀU׊CYZZ枦@!ʊ\b08PA Ngb¬׽T ye^,4 0;2׋mJ,AF#خc" i&H.,ISP.+/_&-xމI˦>yܯ}oO."|zF&Bq LXk]fY.&e]mJ6I*"^Uz5EK 6I2PU2aOA f^a6ڔ1J)#3RdĪ^U*%u "u:13IC~jH;m #3=V&nf:U|؅[lM:f͈b%,GhSgFR6捌 {FbX,5\4Z&7)Z1~xR_˟d뮵vVݶgC|> \@'x-|"}[[sl|g0P,V Wk?Rk cXn\gZJfR  Dy &3^'N}F%P* Ī9';5ݱEms9.M]iM0ڵq}-<ïH6,sf-̏P0URԠ}|4 ̥-ǖt4 (c~{R w I)!6 +mf~3cƎ_rmoTH 2aa*hvϷ{0DʪzwZ Ȃ{Pd) U_Q;K*>{ >(dЧP,/984GtEct)5xt׽f > `?f[ʶ 3W|Ql+κ&h`yK$NԸh&0P1-3jP_iÜSwuc< ".(s3ZXl[Vy,ȗ3ip+0Dkഺֳf,\ +~ٟWz-p>uݏSm6K,4Sdan>n7<-kK&?;A; HL|D6}IN;E=iJL<#΀ B+ v S51ͥ@tP$FvطV1:*hSL\-M?uW.j-4%0m3_??~%ѝG5)< lqV7703? p"p#k4x{nR<(B@1Kfs>vQ0Z`-(4A^V- iNi:gM߅ho믾mF}eUE,-ˡkN mE gt˲%8khYfhD UX)]D@'!vb[nIDATaEXU]8# Vl,I!7N셢Qbfieyr[qF,AN!؂Q48a/ejb!mhj6]W8)m,-8헰^HF)676(oGb_OFcY. qM7;$㲵4^J؁-j2§Dǚ10`7ߴ+VnJK%ԩS|Xڲ2Z*Bj1c^:p^b2 {^,% - >PlcUcfۢt ( HVЮ /[ņ9c uFn(Xm PZhYHc%AsY]HA> "` i[mR[󋒉Nzo0Ntݨ1޼iэvޚBY@|QM08qCPkEm uׁ񬭖-N5Fևh)EZjshMTe]Nk1f9՚ via1iмgNʞili& VHSI:]l$m6UV>_~/xONi\}?~?? gQ9m]矽ٟ/2V:mYhqT뉇UҋLfjF䪢&[ȶ5Qy̰ {| mĝЛ"Ob3Jj0u<$х @'&꽟J˘xĐ͒lR0C L' gK/@`bWۃI`e1bڦm&Ng:&U|cͳt g?nƴ6mdL&U>{{jr#kZq4ٸcEA~͏}7zs>?R olgͩlsw֭rO2VԲI,WZns+J`ٖ>:IqcVSq31h -q'`R]zB.AsBd\2Ȏ⧗^,,SaVc4s,dj,'fXV-k~ > Hk!6B:h&ܪ=?x<_$9̚9)SV@ k]UrpxD?ǧoëi3?=ݻl5+3id0V޿{m2yLL0lxT\4'+XSK֖h~ܿ]Ɨ֔V*UT'5n ].(`Ȧ[.+|m '^%BD$0\~`_>n[y2L4PeCd}Mt$VJT8L21VCK{@(%CM(Oqa`MMr)֛b% ;aAj,E~ݴ5诎sY~9c6CK0tEUнčk v-|Z[~Cw_mkRXBյ /\Ҟ?Pޘx+n_ι7Ru84 042iZGF0f-~4,*ȭR+۹$č hq%o4Ey`#Hjhs UJ ?_0 + j^e4T=Z$J.V޹oRޏ(/"Y9u\nRիpݷ2B|sۿpC%bdܵ|pdݴUj5WQ6[}h7`8YjHFAWpDSP&M2-T(VhT@_)ω~U"vr HPy`70y =IF^]=fmVAkRrw]s|ZхEN-i($?7Xmg[4JK?N}QdKw(O]F8?'v#kj‹}IL2Ƽ?庭m<%& i}\?y|TʝTM!|t3Og냈T[-,܂)XO[7݋&TgKWG%mZ9ǝ@NAh)RŽKL3, ff 1J5dxzU6線Gj匬""Yjo"zia8|ᅇ{tHsBB{R3sf"P; 3:{~f"\ك):vy˟($֬Wlc38{f˜_n>O~omEYH#mZeRya6U^YmL>ԺV< nYf!37ZO(e}1jFk=,+wi-'] L29oƁ>sxNf>kyOH אҏy4֖UlU zh/N^ٖy*T8hs@RSYl:NjZn֙=3F,6RaE ys\f#SS{|G"+X10aC֗_?vN+s^Ju!4&3% h^񥎅)4^-[!IP}F̳0G?iDuRy;gxkTD"JCgK1aV_>w`i.WkCK 9WLڦ,c,e 3>[`mݟo ٙ(un٠ y2?Uey~<" 2̢̓1 4 I2I'&|8((TlYui j ny/>*+kDt<,-P vىtO6qc<1aDǘPxXKOhb&.2&:*/qi-+z-J(,Z^1)1!mՇ7WΒ5 Ph,DIbbn-͖K|PaDs&*fVusbxδfP{0,[+QAmo7d"lB{8lr\)+8?'? q>&u T52.$JY yˢ?[#<[ jP+k^@VHłdu08E\% ^uayLTLûnG-t̰UlC+ȼui0rfqD\?+e(j"bpU$\)nB)_,Bij۲c}DP,TBOqmh@]),@K֚!A 2-#v'X\/Vzؠ* K 510U|}}oc3Ua #%.v^b;9]d25 xMLW\WWy Y LxkLC],bN7#~Ӧbaw,E,_boҼڗ"DJާt0pe焞 dv[ASt'o<"@_uWsŚ)3@Hԍ|5>~ߦe1&kƈH[2CkmEi3+Va&ʀ!AXu9@*W_=WT.h䋺Ȃ(zkÞn7DƊ% 3\ǩ\|y0b뮅"bmT xB$cԙ(CcWIn#$tY29ʤo({{B Q$l@ LE'fnj\UJ2|4V:o*yZNGNihLъYpeLBX7rL|y`zZ^ID e2ZFŖnݰPLYK_⯿{x8(6t5?֏/F~7neB O&☎d3{Ŋ [ eN-4qY pr,Qr hZ煴RmL>ctSqߏq$JYP 5 qTFmB\ +YZ0ex3CgtjcmQ;M"[oŦ-UvyH2-fsH8⥯}YCO#Da"i &暪CD4i~~7fEcQ~^t0t>ϦF"|R*'K%`͚{@%9-viR+g132}5DDP.Q0 [_p 05ċq7h,Icy6yf?~;a!^/`t›+XqȽ2g.pR$&FȼDS,5O>ݏN{Q,J~|UYdU%uV)\(THa%: "WA[}fyapTk21;7386_U!+I̺E36H_,$uõPZjKe % fH4 px?!q?ss|m )Ş0Ȓ|\hn#9%yc><c>ZMHJp5 a!Jek ץR+7 NfqҖ6ѮP gi<=„ɈfkrS-ыT~F Ϊ/^TX% LE, J3ZwLS2_a4͊> 4w7c> [$>bdx+y:miQcc^B A)jZHdfwK7b/A̮0yکmy'㞗0|3t=GfyZYfg@V #"tY*, MI-B,c]I*aY}lH$5[kÎ2HUȼ K3\ WOǴVDeb\?7<|}<Q/XgyጞߙyVs:u=vOvcH PO8`y;,le$L^>64+LaYWμ+4"2},R">G;dL8ק8M (.h V7& hBdR6bn D̃8 J@&fϏ2>5Pl9֒3+ 8قYg13[ΥK0'/ݏϮKe,{ X^J>`bA\1 ob\p5ޢE쁭@D^hۅ+CW1tY\OE(5 @r4ȳ.Y) <1siq䁧V ؝Z,A7Zۭ̋B Ml:8rΞ59s GX Padd7)|_k- F~0x5jP6髢/c>IENDB`gift-0.2.0/testdata/src.jpg000066400000000000000000004200401513354670200155520ustar00rootroot00000000000000   %# , #&')*)-0-(0%()(   (((((((((((((((((((((((((((((((((((((((((((((((((((" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?o!r}J/= I>{eXӯ],l"Mc @ 8|W 3Ehѿ{(0sZҧ+ +7u/=fMbPl$M3F7hO.J.;Sm>h-2 *ib){m]Ҍ'p(JTSP:VlL5_JIVId^utu9kfeUs sJ@R$0) AEOTcSX(IQH ӕyH KԷu(Ģ59*"oN+^3? в-"@+'WVcןQMe9Ѥ^=mhcHUSӿjôA=릲 _9R"qȹP[R3WXל>A0d ޺;/-;yFGsZ)~zUF$;-\$XyU9yb=On2sO}avy#z _x~j7c^uZe=GJblfF=MZq34fbyVE#aEO(0,Ҭ1I9;)lk(Q]UAb$8#j ǡU\?s`[2zU`qrvz )#7r>G1ii{x 8xΜsDYB x=?UQ:}j@k 2+*#bjc+lZ"84n7f3 T,z7<ʢsyϽH\cޣ;Nxۚ?261u9ߩB"p3P:18Jz&Vu{Ug<iO@(,8פxJL K| [`5I]L,vQmǔh#]8/۱c3]micf 4j7Nɂu淼Ex]H;gך-5v QT 9Rzfb9=?:@CR NH 枧!*T}J(NOʔ:iq('$qHלzs)3FM!#4ӃN"#4sE8L_JNW:i:d`qYN'(`?OW7pI s֩ớV ,,k)VڭF6|'wc1޺M/]MfH8݃q^ONL3kʉW9 Sw+ uj6- pGUv$Opx *([֡i.zk9\ϥj$tp$(>SIn];zQѥoHcmfKR,jCMdmWQys&bs.D r'U,a}:dۂ#߷kYWVyRbIXZ9RvVQoC}_(qZ$̤Z~crtn;ᷓA[DYD5 AJpi~܎}ZŚDޚeךϺz{\H⧆ٛջc^Z>d;ֽ9-2#dP9`>sYO@Py*::/* css/߫:P;W[W;KeB>?ʘkMzxYs>ozr(\K pQOz 0R0R-M"1)MicdO`Pd5JvrEbTSxTLVSm0lTsu"l4qvPy4;VRe) OҘI#JB8#>e61Lj 0xr 栐"J=F)b:bӊ~J:P+Ȩ\ U95 ;KeF_ZOYqREw%hh.S?KH<`׫hj@tv6$ 4^jEV$\h_Lcޗ=8_jJ>3G!1@N @Ui)(?rt98q @8/_zʜT1qi1ڤ;P\DLlՂ?Zkq@gTq&0}M ?Pkk;IM.m_5?p*BhnzWO:uK 8~2|v pM{ې;~3#{шy. =*^L88c^3Vv8It鎴G_J1ێxoQޢҔZ,!TzUz}v-!9qThy>(T 8v`RE-F}3Q?ZHhMLxwҺ/ uҹ}Wن>\WM6?mRuBlSl=*Pު -u1:ʎ78ϥ1X qҘpAjJ%mx~Iid^V{I'ҡ'Ԁ_J SI8$JNĞ}K0{R?~Eh3qiAsJ#hXE'9=Lr:ps=qOpҸiVvzUpHjBjp7l|Eg@5t_8KhN2+ϷBso=VobHیԲiw(G^$ls]Ut搿=9TK>vF)|џ{^{I~>բtKZ_t2xi :5 !1*3lweݻP'9z5fjyP'yH\~˕'U*B)_N9Es^:zV9?ָVFUjɟ5>ye/SRzijnph,:N*s]TJۘd8Z[KG 8i՗DK4?$c<'yZ"K+#VX02ʋ'q\򼵐R5&OlvV73_yByQ-"6p3Vwn{Bqذ qTah2&aZVW-FTbƸTqhBpsRg_0&]fQ?Aqb2; !q99vc=1\Do܃^C[ta^k\68b";̷S?Z|k0L ?:*^,b%p]EAX~5`֭XѦˊ0!r>:Uu\{zNRYS1ҏJ:TԤ2e=00*];=}Ba,1>A4N)^ W1p0x?2sf1.d+]\80=3+p1A94=֧"dTFqLSG|֊B$O&iUrU^Ht@*ʹ'j2;riX ;:vb3zc֥@W<ҳFћSY TK'~33IQ2?€qcҡxNmf?D&xjClo֚=y4ӹ 3c<jD\a<ƣaO¤>SzZb!a8TJzOϽb9^ݩW=–Q4jq]ݲƩ׉cD^6=WiQBkҦmݽٰ2k _J:`~t֔=(qF3Oa>8=(ƿ8#S>:Q_52REK.YQ{}EbxI r}GHVGNEzRW;| Ý Us9Z񶝕v +c+.0G'OZcf@90NqOu#ނ:*#!(Ͽ򡾟QFqҭԩ ySOL9O΢jU8#TR8@x8c=h)1)&S `)<wjtꦽ Y`*VWGքn##ڳ&Sg#iYp:U[izհjA"*}AQ%S?ΐ}ӎ+&g(#Mi\b?I7wlZ2H㷽5RO >=ifJgN{T!G{SqM!MژdL =:RU`PH班D?6sLP<0Us֕[=qTXY@-ҽ_:hӾ(#<6`K ]mZ7([Xb b͌ [V]xp OJ,un o:MzUcsM9HǷ<?jYc޵Wli$qI&ȵ8qZV<5=Z ݫT I <"{qWɸ^q]3+J9kY_PinaJ&&_¼ݤvy gcMjxS:#S=Md p䍍!N EJkd'STӪh `#-FSR"Arp0k+Zp)ةlG40FJ%Q1ҡZ+De&[ƤP0jn*Mԧ-YȘ2^@b*854+,o]릚6J(lQNLp4hIwZV#5c92PڴmڤWr*ib+;ϘQjBY3'LW폌XrW`3JA䊚)8=O^w4O8Z gVɌy$!/δB`fk.w>nWPjMN6fW8xk-B0cMSt7ҏ֛i2X~4֞LNず[w2P=*EzjHL.9zV#Z4F=AEMZ=SJm< iY˼a'ӜLNclЉɈQ֗=9)z8j'q`my1# zRu=+uҚ}iZN}O;7ɶ<;wRy4ǎ: Ҝ‰ӌRu>qH}r^ kRd=z 4 ✣Utsz׊`KiXLi6H?ȠJta،ZL`j\p)bh7 [ ojgҨhW+jiإ#SFit*7CT@G'.(PH3R)N;bEd@䎼P;ZaJYfa?s>Jjzۯz7JI'ZUr3܊dX>Kq Mp)n;҂sӊc)8\H bqu~0HrIA^vvr>8ՌM n+=z~ȹ`^7}pnnY٘{Ҷ=3V7"vxTy9*ҷDzai3YA?ZdsQ1'&#m 1#ce57?dA\ aJ6<ڊ)1]ZZJ{SN)+O5%X Ne8`4ҎV3]K*@)+,nP0*\SVH֫nA%b(`f)}Trw.U'"y2zwlУpQMEJO4htEXZQH:Ҏ u=y4R2E&&\[Xlg哻12{V}85;Mq˽ִ3KRKҬ5dcQKpHQREˋN B.=j9nZB#'JІ@@5[ 洭z4iq@=k"G4jlND?)X4;!l k4$Y[.g>P:Vu25zJv99$T#ݺt93^ X:lYIȣa Q ҞNIJTҫ*T4`-*d^&3ZWLx@AthU=WJxt`On j#ҩCW4Pw(a9JU7q81*lqQ24d M`ӊQ,_SE)ԀsӶ3J䉎:S$ ׽h[T;MyzzI Bк(ҼyUn}tFc∣.qQ\w2zY:v.HNFzI`XnN&!w`YQ#Þ^AdX ,~[uʊwGkxYqY."pFIM'xȊBc["%xu/`:qMq]k#0QsZyfK@}cQJHKm98 Uq*Dir4R'Q^NzU 6Rm?iGfuiy,̪I\ Zo Hπ uKN9_ֳgH!:G1bM#bs5=YHSzM8?60{uLݎcZ_oQb,9# bpCeNI*㷌Lw*sګ93UU5nvTl˒M׏L| <?*sHPNzⴃmU堓MzU'$+CH@ոt\`'5iD(6bpZ 1wn}T`iT0+xF^rw}̚T,aV!'x`tJѦ|›RLrcaSm4qOVIM5]4<ҖE5j>N3ҭFՇS,5M=#P˔#s֡fM#NiweE4h%.(h)҅'=boCIc)V5A V0JQFsg;2k÷%L;&tNqmcQWrLM\Uv*ԓ,WlwYVBZfOr+&1wEF84ƫ+p3q+h6ژ[Ty>5!LOzn都3fNzwCb)#aAډ-B'B8 \+m~GJETARM;rFK&B~S]|08%ӖUʎ}GԋK8FԞYI!STgH<=(⹀ڗ=RKWFprj,* vB&SϽRj6+hȤ pI&^ kdP440,?cj_Q sү 6Oi94c?ΐr7pO`81isFOҞW)=KgSҤnGמؤX,Lg5.u>bW&(A-OFj:I"(FLȇv@JIQFG+cz %crkm6TӵpMyؚN>%bqSM \ hj ZxhҜ08`Q3ҤQI,}idg(ӔcS&8)ؤq JvPAVTayS'aiċܚ 2kW`叠O YڀXw<4-g5o/*4a@] $lU&Œévd2mhQߙUdx`0IO8;JcJ+Tf#Fh":sjXEC[GADsr*ɹ:~5Ab(ۑ\i?+dD+]qq wl`QGS[7>\6Zg"a8סd)R9''[r|/iZb\s鎴WAk;HK#d*3Q#=8 ˌ{}(W.Lm ֻk)DЎW"e'Mt ?)5=tПBƫlX\$r?ɯ@̏=!Ąv*$+F9$0@b%dB^iJw?R^=T8NjGQXzwy,vu t& r2;6k8ڻaGsNT!hH=:WOy6wɬ6HS%;?fѝPX*NSǞƴO:HbCkl,>•I:T\&QlH v:Ujua#GͻN:F0YMR.۷g* zJsLHB9=);9M- c?d<cҦҘzGZV ֤\48#4i$qH8#'-͢6pRCV$~3U%oC܀>)LrGZ7p;fjk;S 4ћEÞJ=P3x |; q{-%}AD6kS>0/Te nzߕiOYH#=ts iyd]ӭ6KkBJ飏T9Y<5d$qb&"0{ӭK>ݯ_z8"C`T$Vǘ<ֵ#s[>HAE_J4#Fx2H_Ϋ]8\֬Kq~}E3׿Y-d%⚰RA:qv9JK@RD)㹦> mcbԑeZSָ"LSh2S:T1R`6h&m-b3Vc=9j+6-;974 UNBRRd*VS5-I=*Xg8۵GCZW'޹v%H %+BkqPvi#A+WȇHXr:Ցec5{7k7RYŐ 6ҥ@Q4e6cN#mҚc#5wAFGsiSʷ>ݪ"WLd_(^G'a969h-sHjZ@eh(~Uca"oKcU6e6éR=F*zaUȧި ^ m&q֝Wu OQ^:JՈ}Ja8Q75d&{(ɰ94Ҩ(iX^yK]\z^hJF5.7;e9sީX8lu ySֵ-I"ʔy63q.کͥd}+xF܂9튫(ULɻG5P˥.?ƳYǵ2b sE_Êw8db8S 1qW"? 2l,ڲF]̺@*88#ʾJ#e[˹Uyrs1t` Sz 3iПGgJygl[ G^Hy=Vrsc\N_==1Қ5s95fIC~^6p waʊ,aT9:ALr*9+qꛓin(@q1Q&Gjy==)#t1ϯҠqZ nO(2y8pr:ҿi#*;ޖmVERPNh.T\ҹZzerdw EQlDQWgx\:霢2x5Zo^=k26sMwZ yp,jEomP6ڵ"*wk tv;u\WBf|\ҳ/ڼcl`/]@Ҕ).[9TZq߿JA3X3_{ǜc#'9dp+Vr A_jklFdw l/ԛF9YHŐw4)VU@RAə)'/9h>^ޕZ^\PW`S[~Th6qZP Qӓ5Z0$+t$"ݴe>mT-qZPmR-" d SFj4ڭ 1["篥4jQ }=I sڋh.i ɬgZ1'&0]T9''i6+wc{מj $wD`}kЯtG9 p^ @+4􉲃a("}>'MmCxrxRXxH߭Bn~fl,D;g98VRCʯmr:<aLq{T.r֭E"F{n7cÅ#bc<籦Ms=ibc?]aEjGלT8}i~0cڢx}8li0p:zT2Go#~)>{ K;ґJgSʖ)^ǚ^qU!Ӂl.Ukhۻxe[^,kFѪ<_ ҀF}kЍE%tkklJ؝&E'?)=ŧ(5H;wApX20>qZԦcʕlq:pf±\]я8e9IIT8O]bAY흑Q:/.-|zJECsk#C{ #5kfM/˚.:֬ޛpp3J 7 S:ҩc$%q*GB-Kpz,|![W-:Hßz 4jfw نtZq%i12F?ƻ-\rp=kI5R)j[5?8JF[. =]7VsEl{R%y걶wt <*OC)$k xz`f&EM~lAPKL4JJzPrL=h$LP>ޫ!eR$Fi8aj6k$ X>h߸5}VA,S[Z%2R(##ΣP|*pqvI¯ #W'ޯxɭB$3jIsjv5s:R}'gXd*'Frj'r?#>pN}sҝj&z*V\sɦ$tFGU9n 篡\ 9N[-+r85VWv2w;;IϭQnjI{YX&e ֧z9cE}E j_khX!ޔdSh"i'F+Av'?oF,_0{f9zUC.sW1F#@2L Mj$R:UyTuU+F\iJdKjY$SQXc>%A{֝q+.݊MiBOjHӷ9VCsY֌X}s[DG?Yjֈdzt 뚬X=Nz&+رO=ҳH^=yB Kh4ĀO<fEd}\T!Pbl'֠ϯNǿ֕2m?B L?ZϺ+N)JI!7bkZBw$}k^{r1ڹb'#*.̽ $r9kf A5\bAX zTr^w$Zn95I}h$u4*|c,x g??򨔞ޝ篵f;lġ?s3YnE`F3ZmF<泃8SE.ӓҲlR闁$c~Pr+ά=+^-m /SggUq8Ԯ'4Y^O^{t_u7+]˿#ҋbqI@NGҟ2QyAӽLy4n'늲 SH \ӀQ@a=N9ɢ؈ 玵n,y5NG+ONG|ִuZ`*lg=+Ej$*fh+#Dsb[y!ffݜbq}( 1ӵYیH4!q~ԠuS~Ի}?}JP0x8TxZ,0zӇNzdqNðie&rZRf'ǽrs}qM;nDm=ZեI*sPOzi3J$)nNvs^Ȳ?֩WV(Hfxgndc!QthWN}z-82渏iop&Llr1]H][2r?#Y7so1bNzc;$+mqe9uvcxaqEN6^wsVoMbw>%X8!q5xzi=L\Z)zlx7nW/BHۋSZv*YBU/!d)1 wp8IQA+eOtiרּm'Y՚X^M]"p\Ƴ9F6ߝi)Wc ^UThp-NvG9[ Np=F:c ⹄ )s֤\ZJdm׏W:mV;xǒQe Y5+f70Rnȵ#WZ5ʀ1K}B渑 @rF7P XlsК.Do*VA\Գ6㜊5З|FI*8lm]erŏ$ɧ s8ű S4v9Gb="P@85!uI!OH\j-t('<Ӳc,$U?*Kr*|M-cxzWe=4@shw;hH=b7 '޵Ѳ3K4a*ڦwl#?N9cQlFGGTiqkZ o޹£V֢eÓIB[/g$VeΣ)#Ua0uV6" `t#.=?:)˽; ,Fɻ&=#L+x|bLe@UR֞\ةNqL,5FO@*e\Ҥ{P;v>OJ\8NazIҔ!43iq&= Lqzn2{怱>ԸOzL~YH,3)N=1R(vS`sE&23}St!>ث^Am 0jW&خWjkm7QՁJo]ȕ8ѥ̪[Qyvhs\Lqi c_jQLXX>!CدƸ{qj9dmλ8%9]W95TO+<ij~jIb~װ؃D R3CV.-t@ֲ4nXh]kbXX ֨tٓcCZjI潗O\کׄXG!Dy רx/W1:Wm}d]z|d`\dsօ7$~eӂi<{V2$ckqw)ӕb@H~a:иC)r8b9cbu_.V>ItDwU\iko-zu\dN6 =pk,q1zq^g^3<^w_|~29]d0nPxBpAzCHbJ3tBXu.? ՙE,:R kX)87R]v2[oR?3p=p]?ґN쩬fRX3*JAvMQjSgFjJ~S׌,GJ ;hȀ1a7OZ댌I=@!1V95$t!0҈z{)qhz fPMɩ2qik3H8S=Zvm<g`44mY'Va<~5wC;^ًyaF^23u$jQ#ʭMxǿJh^Ot}"{u1/ Q'*t!$g]f@WbNZvv{U[})@XZ#~yJN?_r35c߽.&bMa\>_ҹECsZlg KfgH0N5麎जsU[S c=x:YL +xfwUи]<5[YK^'W3rpw-Ȓxr[mݪWܧPE>Xf}" _l?Kwd˞ e)44dUg䱫qHX_)D >)MH1bZyvROӚ-'8C# c5Pvz6(bs&3&guA+3h N7x=vw vA5S2b4ggNQ3@ xRiy&H 3Ԭ8F}*ԉ<;O4u"86*,hG0& <8?Z֔7j\2*$?֬G nF8 ?i")q랢  8JQNTQ9zcڀVc@CzRUDҧAH `tO)Td.edTУ#=;`g71 ԈBf3 ٮH|2 ۚ@ۑ\uP5" 5<ܽ}ʸzm|~oG&hu0Ҽ+k8JW>nEBA.%Mxwe8?s3ScG4mAWُ•'X*a=()R(rzS qO+J4Xi Q*zE_֥U)1~Cڜ48憄491Aϯ=hAMi"8ԶҴ#5"q=9xY[8T<1$I|EjjM$' 蚱Qݨv8 bD (R@Cָ3=? \ QяҡX[50׺$PG2 W7ZIkMLyQ=ccjq_^h eP0y?^n'ׯFMF 5!I pOe%Yh aURzJ:* )wӵ˛#_ ݯÊgUѬJ)T1AٲWx[O|߫7*ծ< O5ivsuOt ȋ88Ze#ZnE):utBU<Z +\E opj=NY82\2|c[(=nl\eKMo^\ysұMw0<ȭ VLFGUTյR Ib jTcNHA^J#r<7"zglB j>s("LˑScOzXG nNElc"قsɠGLwjhS""{VdU{=֝+ qZJx8A$Q1(Vn;T%4H$T%hŭVn'Ҵb#BHXRpkWb=jI3"ilawPچ#vկʭzvrP]F$jbxJj߈IKc~8` \ҟ. q\&A1eԚ\Z„jHG?Q8f{HW>zzU֬zz Pءn3W#GqSȑJ(5Ze!N3VKϽ7M(yI"zT<ޓ#T>\==谚+Ҡ捿Ҩ,G*E<}(3@ԪO89=:fG9R: Nޝag@y}xdY49qC:~tqwLh9FTu3wE3ϽwzE}9&[eIw{]yCִWJDOlD>HG'\WYpS[ԒG=jGVWjD04m P [\@j؎q9e62>kqS#MqTf+ UW$+IfOl O+]LOAʩo׌ k_fZ&Ҟ8ZDC8E>BqdSj'JD^3OҦ2?5[q-\5J֭}SDH`LDcO(*FhXv>|AҮs{ҰX"5 BnpCr8R}4XV+sje)^҅#Ld5 ǥFw=0:xB9GNc8Zv"󎵹q߯R,Ê4DgkuԫjGAV|#**NUSvţ6xR;gȁN+s"YV1^zW."Wv) pu56u)zTySdL .Aza,lbX/i1562=)CHV# !*R:qۭU9mgTs?y;\c> ҞJ:rh9H=ƛޞOP9:Pz𦓎)4sSOΐ)Azܓ+~KqO{ ӓRaϭ!<Rz\iI稩Bҝy!40}jB=iUV%P{RϵHx=ޜKTr9lnj қۏSWD9((!w·)l+8qNE浧.Va=#GJCdj,+ iD,=+I b6AҪq]FhkZlg$W g,'""{  |g}*ߊPĶl,XW"lxrPÅxwyηhvk+HԢ8'{ʕN kkt?ʁҕqu( q&@gk閱\ȡEVYo##ޓ˵Ω*~r3Ϸ^eѬ\R-F\,^wëHa<~'IV?9ٜ nʖP[=fxsɿiC$O)g,I ݆>l줙yhl ߎ;"8,] G(UR7^y5$vSF{Rڐjl4)q3Ҥ:~Ҙl* W1Ҙ"Gيۊ`^= W1OGe#Ԍ^bhҵ~jֵBFX ,A 's!Lօ>VɥWF݂c =Jr,p}S(-ItG:0bBKa"HU]ّ@'P}d2A<v2kMgVWN,U(aOOc)3 h?֑_Wp82ݒ6"PvX;H+5rz~&XjH5ЫZAA5%=u"TnsִQx).5)vBEjC&;ӣ`~r^8ށ=Gjv4PA)dAT?>h޹I!XFNpkw8w22z58zӊɻ;'TRɟ01j[T]3)8j11 үalF'm3ZI6N[:\ȗ!\)J"-wU9o9-i1!ڢ q¦yTTO1V62ȹgyr3ld4gL) ?1Qț38YNɭQc6@ TfF}Z1#qU{>#^?X0:cS4E'iBF\`)B ]\hhҸ4f}g=JvST[Xq%ƿJȇj.ڠ5bB15]*KBi!f7o6t3sOz0>Ԝ:Ru⋈V8Monis4.F0q׊cOz~ P(jr2G A5*hq<xS(ΘӂRޤUCerr?άyYxTWz8DO~uma'TsU$"@J!WRf"R@`iZv LY2sWOnj6>X,K\[s^.UA" O!O[_T׬Rv닻dԵ(FN9WM\rW0Ph#=qڽ3. ܜD~zWt(s:v1gEʌ+5{tVbPRL^/ >$++&kʊ03y>n)8=j*=l\h>1vXuFxŒsY4s "Ҥg!I=9;}+BHfnVRsHǂ#E,F3)*k['5nàYy?hʌ,}9aH9&~rT(;W'rKD9k&"# Zf?:.8a'K^1q}6\BjC'#zLYqd^i*&T`+cR:Ң Pw*lP[[ԫj6>f7ֆ22`0գKG}=`h[+ӡc=d*#$1օwFu(e(8;35$+EY1e*M(RpyI~aHY(pJSmXj/nT Ѥ]򟛸)0Hޯ[<l ]TiiCgڪ2oXԣMÎz?5TSXjǝ@>5eOjbe֤VTg$qRզR$`+ h͉9q}HcR̢Kv\y$EEMVwr),y}+8nvI2pqUgE8ǵsR6@z oe49;VLפ֨f&*,;n*~tҹh.)cH悾T4&(+M#QkY4;(9S2i8tơ\ o LΦN{Q7*,ǿ4-?xqZ )gqRm޵RyQ`.`=97R,NzRIes]փdfRsER/!.wYĂtZB>)=sS*0)0U X:z8A*M}if{qڗ`vzNّ$*wTm"gɏ&& n~*'Dp*Z,k#QyZȲgZD]iw4ou;]>&8Qp=:䑞[';WE8H~H|ᓞkWS>T JӴ1*՘4)ZpW)˙ֹ8ց ZBpy@NA'Fxޞ߇4yP!=?Ȥ>)~fGJvAϧǷ Rp=Qc)o@n ҞHǵ0hlB:14֑ >qҘ{:@xJ^IsNϥ;`=3ޢ#iqJlxOT|<gךbTg⚀g&QHLgJTL O5i\S$|jELcjGH2@jD:T<i]c?Ni ]/&9)E0+sMte=5bN)lF˓Ƞ lQ ĖSN>`5nR|wwfҹfp$ g֡}OQ+{PHiFjy7CU2zĨzW5;bUtQTpjconƼU6V9z\h2Ҹ-n˽gqʌ΅ˌep:dէAcg[lӴ2L;{nmοtYkpׯmm-1 h+vqT;bwfBĀp+N($e۫AQڽ&4ԭ KEV]zs撦6d¼[l`LWW"`G^^! ˕s֣U;)6RgL#9cxɦ!q!zҔ)iry"cq#I`lq lT բcniVq=jی4=3NN v)uR#~<gI42[SZH(D6`p{Vֲ+1pqS()Ղ3'#' {Wa@ѕq`k.Ѐr:M|鸜8ȥe^\#K LJK5+$ ꌔEYq?JhzyRe4=mcڮ"~ @Z0>GҷQgUºNÜw/`AvI>:r\H޸RF+c 1)1O44 AZv18 HW-;oXy*(ZW eZy(zfh"ĈJȮ(5v6q[\c3V"pzUQԒ;5#ar X+KfE={E1(@#gSԒ+,)ۊre[GȄ1Z>x: 4ԅ1@\90 lKTOq5r-"k~*8~ -JB,v1W|cGB#*eD@1)ùoxaP֡xQO0 9fpyI+T1*j-YsIgBěΝl /U;X2S]FfK*UWUm@ꦙl0=+@.?*J0$S9篦*r8$zʲVmiy5zq5VFSfLȦ*YHݓ4:q$b8!3J~"'519Ssְc8o\sX׫ި (Ꮶj +hF9i&ΞQ-SVD{RHqI@\F>ƏCWdS bk}UR:U88kxEɈΗoI5sh>Q_x Z%&u-(<(Ǒ֠F 0x*QcxXrdVbSQFFsN49j׷Gc>X?a6s54y5,-_:hgӜb= [sZr9N@ ӶiJ?Zcq")ӂ֧tXOUoƜ0-)\S@Q$v8idstijMߝ9Mg=v jb4:^Br Q琬6<˒3]-*,cg>ÕWF !H|ABI=Mu s}c94WqoN2|F yJF=W`ҭi 4 ɟV0IQj7LUݼtKPm47pݎk[TC W7,Օ A ZscH,GrxXӍ>% +:+ԭy9F’7S.u?Y$RH 5B;NYxx$}4?"[Z}p&q­h4U g>mU5yUYr-E\avUcJSWr1#8?NjuTI$5ZEInu>j98oϦjΤR-Rߡ]j֨Fy;\Mư}jϛV3u͒gGI޾pZXf.Z@G 9"J7AeQ'=(褞q:|0,kEtppzVjs-HMl7={{S<·6#c9 88V{ccoH1i[HTzM 1xwmJ@DFo`)AHAHA*w} Va]09r;QfCY*jͼPZcLOZ "b>F=.85Zlʞzmgk ?|.)LSL LEvfCi$ǚmӞ:Wj[*6EF7+kWfzgRrĝ*QFv.(jO3VcLu+Fɩv)H80TJiQҕ*OR9^pVB8Rnv*d!nX5|GI/yǧn+0)7>#;S2)W#CҹR3&e Q0( 䞴q9h 7+6 )50;HF{HwY0Y֜Oz :kO~jCr{T/\䚉l&t6pp" qRNn+H!?=Ԭ}G0ԡi~<+hOOO (ʚCAQc㹠q=( ~ǽ!ZV~ 犑4Qk1jZ7+޵.X{ЇPwOq^G5PGM, ҟ;ףdCq{Z˫mS3-wB PIsHz`ҘNfEH&oaԬ_HDLZnx ?JF7PpxN-?¢' w)@xɨOU(>A{P5*!Cޢ#ڤ$Td P+,׭/ӊiBBb7Lt)oUHSscjV$R*$9-5ݵ9iR2(a}*e7ЏZ5+dxSiLSs޼2jVU1vgw5u(U)Ņ""]ܤ:V$ܓqUe[8Һ e$/O+OZNA$ ϸ&@NӐ3B-s~HI1U6CW{ ֏AڬlQh3˫?OǏ Q#11N LCH#^Vz*'~b1-1NOZU|iX$g\Z̞|Ӹt$}+Pqk9ɔdƫ)fMRFw2>))<U8\ӗs],qڹM<ö{qQp:*HڊT؃Aѽj>刀Yj(gF)\#8XX Նa>sO=Z[s's\ywVV@d) K2 =iBV"++sׁ@^֋O<:֞Zv޴X*b֞NQA} (fǾi9)c'҆Q}:b>@&"N =2hb3:.N+$8$+ijX#*ӓ (dڇb N!ӊ%/+#,?£e ֘zҦe_j\tj9֥`2sT2`DsP8XP18r};TGHBxHCsץ(`9D Ɨw?Zp(lgCM=}Cy41jAz)n1ژH#L*z*CcڻwFyTrՃ{ӟ+6"9!pņ=kՄHyv2x};ydiʑҶfCwy$:UYcp+YT:٣LEBs޴eNQ'8@ÃڔsC8zr1KK{78>֎*Vx4}4~bg99ZV$w*"@p0OaVlʐ/8$v Ur72H+Ty+{ź,zx ?:Dxe?uAWf gkפԠsdTe\h\7^8FI5 )RL. ir[+YAϭzdlV5iH!3 >kfsHyԹ㎕ 7;xm܎Jw:|O=S> Eά zϺs?SS72fmLc?JzČIT;ԝޔc*X;qRH9] FߘU )XMvN=zf藌Z4$sҮ;"zq֜EaF:{ֹgJ`;q;bQkC TOfqTo;$9Wx08gC׊N""hGZ,dd8qӵH tj=*EqWM5ǏSt3{W/IU\@1j6⸚uQJ{Σn5,dLyQI8{w1 1T٪늑 v#Qɧ;gңs H4އ&<)ڀx<~ښ9?ʔt1'ۀhaN I'~/L`h?:pc֧Ҙȸig ~yX8] zTyҁ$VK|.1U:~1Y׶ycڃu,qwejWOs+&̩8 nU8PUhe4H9#tބ6oך[&kȮ$55fhCz(գȓ!˭7jW4'dI@Xi\MshPjڒHh*̣5LU;qaKcGJK'"!޼ì>JmiLG~qzMR oJ6S2t/xaMf'q&OҩN''R'Vsz"e03BaskdɌdzV"qYu_]>vPӽ 6{ l2AW;up<ÃV5Kǹlg iNEtɓ^BrYsӵz^aҚM%d8B}3OsןZT?t$lPJFu㎴\SCLdzS0 ( ` h~U LRd2j;ֳF=j# V~퟉W.= FP=X@ T4yZraD# 1W5*T{gq26vq\7)`109z|g+Q[#׹&V+Zk @Z:qD#WӀvi{V]HzFsN^X ap֘sJnR8晟P3KҘGiS)0a^jryEL39ckI,_i W4- kTaکiҺ[TzP %Lg\~/]Â=j-Hc1>J9k}Q:jSk ?KW $Uj^ZEԴ7@֮@*}Z玞sS=*AӊV3mC8L4JN?ΜЀʞiFF8H? \EtHDzyDcScw2lgćzg*t% r7aQZy}[>Xڙo/r ܚJ^ifA$0#/9I%1Mz׹A8FawbTp*v֡*w6ӵj`N ;[Ҵ\āio՘r^ y`k :܇yj-/X*L⸪A=l9McR㎝):PqTs; @q1~#QUnD*Ҁd.FdzsCQHVqR#P5 hhQ'OZ#43?zaHbFMhiqZ j0?Kf5ecU Lm;'\Ti@~N<`]ij#W'ֹmOM[jC|[O&!Ao61޳Ypk~^[< iiRQIڅ¨YfBT5BJ:-Ǩܢ ֺ,aV- "c5'$zPE9WPųNfѫ $BY6x漨gJz)ʱhGGbBuSN2KE^Vyz]Bz\o3D%CR5Q=yRꗠn iڗ.Ϯ=OQ{Y%T-SQ\Ŧ٩7OL+d2V@Y$=k o4&I/?p⠓Ě21QFEyҎL{8)at J߁ZC9w4Q)-VOw9e6cP@)қ=dnj+Ԙ :޿]\>FgywhR R@bҊ ; lXbKAH4>e(="s]q3Z_?:}Tc['q_B~֤NZ&$5d6G^:rj)==sҩϻ5jSޫKLOQ6@I_ǥZ@<c㨬 \Ƴ?qn+ dFhZv-\1YE7&wT#qQcZkS5gUklCx^ g=+Fp+=(- "01NjTޤ+{B9瞔FhM}ZHEQ񃚶&2u?џ4⋅AZwsޢS8.;ZQ暣P?4Zh9>0Gnv'ӭ()9U u>)/^M'YթozV]5dwqڰ񁥧<{ y'5Fpu3zKB;IQ۟<L^2$LaW5I]mdڝ)ֲ$n3q>!^8ϭ2:P:hxLeC@P9BhƬGRXZw>b'k@, <Y~u]*\jc|t10$JG#4U(T}i}hNC@ JP=M(Ը8@Z^M( g4iAHE'ȈZR r; UU @E$3VΠd9\3XLU;[V2yֈO$'x_ Zz/ Q+Eef܎cg(ZHޟvF5xR f&է "GOzx>cxsUFN{{Ui9EWlƃuym'RG]F5l݃>83Л6΃ZXq[ +)\o,wj`m]l07C )rٝtj*7#qq]ILQG' Ң}qO7!qw]ca8ZƘՌoZ02}M9jOcrK©dm#ڽS[ң!+ok[R qqvg]9nJj@0R"䚊n|sQ4\ qLi*hόU}|˞Y>SC.ʎ銅ۊÿ5^MKB)H?皯"^sU>jN gȻsU@58U{f41ȫiXG4 O@s<ԉD2:cT l`r:۵ŪF[uQFKdVr1TVXh| hܣ 29eI5+LOBs&E4EgnO4ni o?t+1溻e6~ 22jŽPi輏T8 \JF1 \={T{Q&oJ̭2qPMFT mF@5ҥ+$-sږr?W{*a*J*N{MGN`ObKnQ5M<.~{FaY4H=ibGOa 4ӳHGRS5ģ4PKҞ9&Z.M W SS*$\ΌҤHZ gȫځ(snOQVaǭ^ܞr+~FE [p8Iqjvq[AǵWsqY2[9 9ټd'UIp\jAZDw;x$;jf[[P)RI;4lTϓywxnOsLV:]֦yIZĶu"gjҞ sP]ߎq\U̦YYnLYfNkfYGbOZـbEUs֭)^)CՍ-Fn90LWaR(n\aI^'sc^ѱSZV[zԧbVǵh V ~5iʣ^j!+®2X릝knuBgC*ȼJ\,pd]Q5M2rT Ȩy⭕N*HE7LګH^pj|֪1Z2/>aIךѕ3TCKryd#U9Kaշ`t)9J1 y.E!=W#lVLm>z 3 hw42TjޤC{UpF8Rr(Rd`@svMBp@\^sJyA;P;rd󎕙.#W=pM=dSΛxeP?E`H_Z[̀Qdi XǟzO+=*X mt;{G[gLqU_WZcOJTaG*ˮ3QTZEW`;ƬȽP:uK _qUg7ܙ`Wn~u ֬2 ԁ\'Ԁg1MԴv4w◎y!ݳM9Nzq _o?x<ʘ$}y0s؎ir3ӥ.O֭rxT#nqWb`gզ"}ոԘe8K°}éIq$@j6ǭR}sQi9̛ܗ8r:n xTTG\WOk FHvyc?Sz2܎Z_֣ZyRt!ܞNƌsǥ(be'&>1ғ3&*.w,'ϦsH:*nTχOWqmumW'Ґ'JQ&cLqJQI:9X烃YJ]drƣHĚ.b+.hp95܉ jj#Ff#"uGҪ4d04Īz~) e:fRrxKvjsֳiȥ'V*ߞ;\(aW7f.ztkR֜?5ygi֘#Y,A98ZyZ$u9[eX{RHŲ`;TJNFҵlF "Dcfdt}iWHxQWVF9;UtV)+KU^5< ;Zqޔ5cuKBr⹶bl8sozX'bǵL7`kn3@_:f0vzs)Hݽ*xȭ?tcӌQ2me#۱9sVa!wU,nW2v6nykAe&kNL\;t\Vjt)<ֺ;[ANԋUu?;9tVY㧥Wry횁6r8RE5m8*F*X.=EVgZsU~K r*=VrOosPf@֥1Jb#Fi+V; LHL8u=?I P"3ag+wicۏJC(sIk`""A5+ 8jc9P<ՎTMғ :T-8B;b!aN8FK=UӊE`RqmӌǽW`UlLj/b9d_ZB+rzԎ|mP!9<%N?ɦ4g&!0G0ԛ)jiǨ➌q_DcpԒ2N9ȯ@O.R=+֫{WEsU7cJs<c'/9Rci#Ƥ'Urz QTw"{})>RD}i)ǎÀ=hN8nyI=MT`Lv9Xc$^%9+ w{n,gjk=&ȧ4xӭd9qVA[J'R%ڮ[{njIhc̘9`>⬤{q N8*ַ4uFs[7gkVt&@@8qQՙs B@'0kKqGrc Bs$dW-Is3zQS˱,sP)Ln@KIL4i3N=ycMiK!( Fx5fm'Pf>bK?YAPF2{uj!U&MTtԀ~t{~W x#9ݽ+6#6ohq[*g/l tx6 .1#iYJ-2:T3`` 7!ZUqKykj;XHb fcx3(⦎B* 9+RXS,FA+X( v mJ7ت.G'IN=X.8^g?urʘJG_]ϒ ͒1]EX(rX=۵"ݸH#J䊴%8p8MtOI ,\O9c]8['T >ԧ{W<19\v3cJs*69Q1XLԀkfcjFKF_t'+ 42j>Qb 5>ˑ3yLd+ﳌQ9;zքa#x0֬FB1ꋼLY85\b ձ?rOV> /"ui7G,e+.Ji Ia&s._]e\Uߞ*y:sl+KU&9&0:WZ/ņl6=N^2IǽR{ti'-&zt(%a!G|ɟJݹ$cCG X6R`ZFxUĞ8h:t=}^Bz015M!v:E໶u:ιn67ʧծџgE9]=@D\Z!h0r {V4*!Sj \#ަl$ĞqTԶ]95CS uc^¾݅[t ~И.!G^ߍr'tz'SRdc=ҟ~llsJ}3SNG1֧'8)NNS)CqdՍ6o"7;@GBWV=I^q|ֲrEr˞Ed ]*IΫ; *uaUAS`J1!}*@=1L$du=[شKyrFrN}E;CkcS2 uHĤMsի}jh[&{sj8 $CϨI^ΓlۥL/"s"Q\G7NG,=j$x9A6,#/^% @>~(㑀*8ϳr#֛)Mu:,0]K5xvmY949=,֒ 4H=o<;A_Jʻn1-2u2 GQR9As1 棼̱[.B Z: 66P9CVipՔ8 T*g#-d(5bIJ+pǥIɦ*ZE >,,"$fK>W)n *f֯SD׭IT?Oz9ȦNUuڦS0'CԪ Gn*g4O5`t5 C <ܾ֣1Cx0֬@\`Q'} 9D|g18>F'*n'/(6;[ה?īo =ի_%X}ԀG%Nkzs<*=!i /Q¬)#,YO9Xhvi=R7h:և xސRj\*/>KAbUw^?J"OJ*\p**䋒r~g,eF}2S9uɬؙ]mԎx5;jJ@j;֠s+n6:tȟsW"~}Dщ>eB&*9.2fR1֩u+`Sp:7WSOsNX87J%4voCK'ݓ(Pw᱊7u.Rw>qI"4iޟΣ-ϭ ǿ5k55ibpk'Wsk[8'n+f3\ˉʬkE^hu,wӭl8 ڨi?/,JΆؚ+|腈)8qSS|+JJ7*ʐkb2kヌQ2ckw9#֖-9#F?6]>mz+ۣ:)iQ19Vr{ v6U)HɯQJ䒱 u$KF5ZC4+z|nSbH!ug9q^gsbKfܤd^M!]?5-m#b9W t1%sҨWp+v CdVS.F8FSu8LOj 09&F8(FVЊ봫:Ny\B;c֯wϔǃ]ySvgJ MC6~(xP4d}kE${dz"S9 xKԬ1MB`sJI $l"A:^՞z-29<0}Q(Jߚ`?J\\:$JO~PӇ\SC+ȼ5EYt}j8R &1I}:-K dwk"yN}+nAW kcy ={TN|ښqןzhpܷ=^k:֣Bz1Q&ٛRRsէ"\U}V:W99]Zz/Oή( ## z*|j9H;QHp"$Jg;ָFcRC.̅r0q^ᛒЮOJ2LQ9L1UԚN Z9xNqԑ&V-[͏60XTgc׌ЀqڦW!^kGY&qZ׆ze,m H`.FVd VN=0\+[ mn}+rH#wݔ9qJ]ܒCײ8QdIanHPWeXۑ1[@lqsZ#-fFTt ʵOT=pk9 jP=T%Ny|֫p;YZ0;pkR}kۑ5j7eܨ4RW#H*bM7XyQk6.i# s^B ?퇙2n^?z58VN=l\be`8*{I)c~̌4pzJjHJEaϥC5GLJUby* mCzs] d ^g8\5k&w֐󑌚[mf(;Թ4cҹ֝6v'GװD#\D qMrT҃=롨AUB{م%nϥtj6b9ٝp;qֺԊy5hlY_54 bÊo Wڛp𮵢3Z1%Tբª#bŖDd4ID^(κ8J(דG T^I5Fqs$J;H\.}C]Ufðm?70 ~+ڵl}C'U~s^/&{wb`gҹʂXW_ibŴڸrk Q.ބrӌwgy%nhyܑdU:ݤUF.N)%fS]7^F+1 ΩMSU 9U$''iH$RqA'NigrO[5Xu=6'Vqe=E:I8&C0o݆zS- 4lg"o\=* քïgJSs9ILSRvdpG5Jl ҳw:}ڣ$sw[w@xlt^9sE3+U:O!pHj;$SȷwfU~9?MN@+bZ5}Ny?F[5b9ϥ@-2Wj< Դ"Oo5ќj(lY؛21R8#Dێ c;Cqg9ۊOCH1ʞ1\O@ǿֻ ٦Y@kv+[d{ҔV$f2+jkrΟm zPHd;WD"uB%JU'R++xN׷!TM]ԍѕtJf\˱IKH\6+O:Jծ)9955܅5ZEOۖaRi:נxoJHzJޜfׇ-Pa5Ҡ ~NW FbV$ j\ ҜczlSryO D{`ԑ9tcL:{Qa`{zUU犞5gR@XqJЂ2 =_}])j?ҬGỏ{FI|cy݁aeQ[?C}kHX bc3hMZģ0+湋#ҽ3bp\@=kͮ@DM׊ TG|5W s^ck"g ~5IՍJYQ=jt8ipfSPWsY㏼1d3秵kFBD1H,Z\KWsѪ K,i9튪fLOkJǙ)6ΓJ,D!޵YO\tcNz_l.9·/\ƞ7DLq\^ݫ]G'q|cJ*JF>Zay.Nbp~TWM.K *"~!^=?ϽXԁy8fp;*.z|L8$lO=$vnq27W#*vQH֐gVcɫsU] .Iv"-mǦ+s< NWTefxh!%H5s W8xwƒA-ݴ?3 KnՔ7hއW l!t^u&4~q^wsL~565Ԙ*栏FwyeAj=Y[ {u+knb`M\EuBlb:Z.c3߽n&J~qTO^:U:ޕ4ϥK;R#ydv\f.ýwu"V{<c& q[+17ޔ`MzMP9{focFeA[ʧ8qvڞ,yme&,q^Uj.<\.W#= dr*}j<`zb ixZÑBdHFݼ<=l[H*k2;wKIH=4.j2y+R2$iU9(8jR96*=K u+ /Wmg0vP= 9l>ҞN3Q+;Ip=`:bi9Mv♜ڦH 4Z MWXwsEV XɄБ\B .o1Tc /tm);$T텴 a#J_*jS[wOz?J73z3!qV"~_ rx#|ciW4y}1r\9,09@ҵ4n,zW|` k <ňW]`vě{Yc+?ϒgpčY72FzV0z|;yxKg'$EOk=өGԔ;-- WSZ[G.@9ވɽOE}rM *ϭyρ3\L`1^͂M{)7+2<]F {+5HO5#9Uy8ԶKd.i,{UYO'tQ7iy=3XG&#cԠ>iҦI1szd8T4La_8՝fLU&2lpoҪ;~wrǧzPn3Ґ&N_p3ZDs:$dsXJ+M3̄09$d[bOlnF7?:u9.*~3zJI+o ^i\g}k^I n1iI<-vU?IsO^cSJ8}9M JH*wQ^::PRSd',2IwpňՓR|ގ.@#ڮì|q;/zSrƶZeIs3։|NJΛUbGN=M`zar{ffԘ}_RsѻXcFjAɥMMH#Ҳi(u5fIs֭Cgi ;M{k^XW#s j!G04z7h`ϥ]Bu^ge@ [v"P%#ONgPخ?$|dힵjXI0>Əi}siA>J<ެ=YucLɍčgZѸtSYcr{Ժ 'ͩdui%z}#TBz+ b*Ff$֛ L`a@9.1P屏Hn'?wҚrҟens b sQ:fpӴHiOG3/Rmaj)PwGPݾͪ=RIdo.F b,r}IRص8q{Ux WzIqJ88M9P8D*xדLv1JS(E9RO4X,dK^gEt3ku5gJdx"Yq5Ӱ!#4H^Y!SҲ(fQVc2qMDTuz/6vP1R㞴Q" Z/)q֋2Fu"GJNS"1QcFzoN)1S_4E^}֦QHޞ)G0#4/KZ`S˻ VsA$`sfrgB3,+a޸y*0Ǩn=+nQ>W{᫆ʑɠ/8tcUiZүP~xnܬ;G\.dr}kӴY/uQZ\5idnT+w\1ɒF?{ċֶ/1|1y Ju^OG`{¤fͼXq; ڬ(7cWZhuN֚<.+O}cq^,m%͵+Y3\oJޙY8[>q$~zw|stU擮*nCdr63ڟ#IRr9Hbidn>`9Pƙ!nyҖ=*"IY&s3M~ԃ҆;Pj$_*&8TsګɞP6WcxȨ@2r9Xҁ =xAcHqzPM?NqVcqU6Hf)$ޫ5Mr%AҌ~,ث3& Vza ?sah~7 ބYtݙ"xSZ9vG×^MI;t Yk>޹w?95h?ҸpZ&fhxyشb:qX&RFs995:V f&RaxU쟑H܄r<ʥqU.fS6-VAEt,DJ$wS_4M.G^NV1=%r ?Tomȥq[ªOrNV;)TmR94:֗ReEJ8^i֣ˏ<w*;AV,YS\dn3P5hJ1ZJQHi€)Z\O<Ҹ 'noZa!sJƣ3@!í.@P yY"<@\yгci9M# tM=]N:)sy!J꭬QW51 RՁjs~\szf$h88F@$ʟʡIn8pZ.i9Pv?A枩R+k0/9*ZxJW ON&9WS>Xd{q֜zv);z ƥAt m݃2AnoK KH眮6)DcC#rx9K`[1rz $#k0H@9={T.F:MMi,<5b7wv͸iL9y׎:޽%wn\/̈q vגBuZ#+cl#LRȌ ^y/s&OSּzsY2"C=yxp6*R÷9g w?7=駥ygڽ)^sA'FMDO4Q2%ԟ&繪wS#ھ5 JJMA R)7n@8 2~+puH>Ց$sWk6I$ HN&+47 M!!?(0J#tJk00GUyk݊G为ڣG^YzdMWiqߚRg>Y3ZGpxMOVy28j.CI&xbHezӋszylky sOl58i\Ò2jEEXD=H#Ui }OY~SڪȦˁJOyUgOEQs5vH=Ue57{ #/45:H_FN q$#?OZyֳUu>PGqRg'JdĀduSR13<9~s$g5:M=VJKttԀ Q9ֳ|b4W3` cg-.{憓r%3Ddcxr3d(Uwz8Ds6Ld3֘1G?Q+v[xSS7erJ+6A$gַAGR;)~r8>1pvJqwgT -579u,91Tٲ{ h)'434& )4Ҩu6֯)ŒԖvqt5^?WINAۂ+HTqZm Q@8+U FxK$E1\F4ܟJn4 i$еܽ;j0XNE$҈koqhI7tc*:ǎ&yP6dҝ=sY?\ZfRո3Y1IV\CF#QTO֘ɏҚHn=8;4J3qS#QAҽ3wj>D1顓ƽ1VcN^@j!vaDAVR+w7@qߊToRhdO5^NA櫶9 drqTg H⡓Y)S1'GbYp2+6Oaen+TsT^Vh6 hھ)Ԉc'Yp2Pv5YW?!#VGr6nNOPlӉQislGJ:qK{fӌtEÆG֜HisKRعEXI}EVW*>Y\=k?i^4˚rPozfORzD:uIn*jsϸG_ҳlR*{PnjGPyPM̜Q˒:gҵlfkcJ@1JҞKSԼ G^c!8It1du]9[zk݉DrsQ?Q~֭\R0ꪰz.nlf9#a qU]8fִ/'`>kA!AǵyhEYC]cgQcuSi4fgLicI[_Fpj(#i's{YF7ao 9ZKISw "YL \RO?Q\vF^K{yF;zצcU,mm_zir=a-όͳW>ZP8JY=zyGcU @$#2 9Lyj?;-k6iH$<|>a'*>x(%2V9mz`SnAh.xN7:*S5" RZ:"~1PuHÃڮDL ث~Yeҕ(2 (犪hCi?Lg&"86Ն^R=OZA9[jITÿ^jץK^\ ;Ž? -/^-ϵ9Xg?Z"8ԂLO?J#ڤV<\Z~ c2iܒ}zsǽ57A,Vl֣-qK< f|㞃DN=}jV^ :!I:̛mx⮎ՋH^dA#cZVV+m .f[SuSVEVBګHyjG~]<~u0JnrԌ÷C@i1׵ .sT,MF7 [I4i̐/=  C27]W:-\ 1^}V^ףܿ6pOr$8.9lKq%S,ҽJ.Z4["!Ϸx؍*\V'885”qٖ)GVkf}ڈ2f:V'<]kek$VddJtا[xb0ֵ|9=IԢa,UЩZWH!ֵ&to]]4GAwz> :UMk&3ǛJhӥyf- r+5qZ:\\3sҳ^>w70478vrsPY\4 x!uq?|W;3i\zj+Ik&T`6j-Jri&JsPyYAR٦uڛuMt{iCEsޒAfhf{R1M'Af  (LԌղHkzXH@=UtUd^@"wk ǝ>ƹJDO Sͻ 4nsQm$Z_fUsϥӠJ-2{ DI1 ƱDjkrjI,zWl15j樱椉ޜt&hڬ+ؤN+#A$CS#GL4ՓӄzUO3 MCGVU^cҭD={zW;%}VRy=j(=[rG9>Dy=jITH{}jCӰƝ*t?G{Uȓ'P> NϭSzzʹ)U@<~::Ν׊~qHy1H8!03w#B8(,/XZI 69njц^0Mq&r'blJ K`F3ԥaM/֝uJN.Ǟ^ u-%$g;OJ4\an;k[A !Sjl}6jEZxD}Fn KDꢩ%a&3ϑzKjB qw*d5)]^ S&ZP@=( 74Ps=EGFx!2PxJ?LN- @ ֞y2n=@9G\u/_4>Lwnbi7y;sA#sӿ8[38X؞g5{y5YIIksL bi94;sUe|+# }?ڙ:wa9ɟVj3}1zgF42s8)Oh6=s늳 Z *x(fzY|y^F#1v 93Z 8qZ˿|n#GKI ˹WUu= f;OY jӤlH^;*Ke-jx&bG?0@1>׫۷*A֯􁨰__BM,1a4rGN)jsif2UA_h*9&l5Eh Q_YWOO=pS<ҳ\ITU@3^T4Ww$`1VzT<3+Ap* :i7mZIE˓zZ98GjUJlRBATϓαZ[3"݆3rO+9% 96JW=1W ╊+RxZJ|sqrpzK"f_DE=kL.#5Gr1F9壹ۓgR.<.aZAma)|Nr20jHGKY`B cz*d>.:RҒ0q?:x 4Ӏ9Q3RGDFccNǠg;SjұHz5eLdUOJUݾMBqޡ'K&2}*ǵ SҀqM P$n5+qj&T u략V?B @Zh݁HlKJ3NdE;Qq"{SqZtڑ, ǠJGY]n@:L0z{U lw*(Ttj>5)Y ~֯B;b.Gϭi>FXRb&}$ygޝr+8ׄm~^nH%?V?7lu5T|gbI\VbJDǚ~X4r3֤ ۱4\qA Gvv_ V_ff9U> 2]NH8缻$kqԞ˳y~1>9$Gq"B(JNzUZo10y!)ғMך`8pQӔ2rx^TQTₑ\(F4(W-c"&: sZP8fokBFkxYv*Snx@:T 'DyT{! ]{[qUeCD' So?t$qR,#[{So¤K>\@Uij!AX@GS4{0@d дR8\ӷ9ɣp0sT`ֺQ0zVLzɡ΍j犓HG# HzS{P;9<֥㨩J""9zM^(֔/=9nCӑjS rTҶtkŎcuקֹ_?N3&2EL7HpX 8zOY ]q1{"G&ߕ|mits z++{R{W*Pw>#pإ,=;dH֞tEj##kkrc3Z[8C*Iz/'8JǧW :q}(mskk9o.fVFh$|Ev> N坝UUrZaQw<*8:ƊyGlBî+HZ$֥$OXΠuqqT ?xIFٻ2r}ZcB0.(=UD~Gwչwh(pR`:zSVg?59:u梓5w6ZǽLPAI\/'"p;ҬKsҫ f$jG#^)4こNH}j#1ϭDÜuTocUD5,D/Fǽ=unqR!UsOV=  TG9XCjXNNMB}sx`:֐.yM<F)7rGsICTm=>|BOGV .N>?ʪeҗ#T\S;׊] Q]D階G㚆F¤qNNWtW9kkc7PmҠOJګ9 vӜ䃼Zv#v*2x6_֐QHG5,,K7abM֝<)҄Ƈ+kM?,MZ 8浴@x(5sHhٳ Vn3d`CDq[Rxoq>& p >`FzYRK`խR&RƬ>zB MzЯQUXJiW4(8OoKcmM%v2}*XeTMFӒI~.e0 AuuO1)ĸ[;1mqkI'K,G3>B*2OYԛjOJ8hǵt`zG\jC)y1LnP JRxd qLҏUJzяPy*F*)HH~iٮq5bִnԉSֳkVnEt"Yj(IRDV1UXXd~B11ҟO*MƷ?JoZrqMX*Z9"@><=a+Ӧ:f? JˀsU$4ۄ8VECMm]X52cf%bZռ;zkl\>:S6 Pw ֳe&t6nVҰleg& =(7Ԍ;ԡNLqZ@J!01?J4<O2Ijqh=Z$|cUIʚ$#TY C$@yy"j ȑ1jJ՞,fOڮێT!ZV7׊v4!3Ƕx[u# Ub  tE# UqӜU Z -ڬTsesޮ'Q;ޘ5:NpPG@j]8Uj@?ƀ1ڞHsJqӵ.8N)HïނiPǥ "c=x=LRY0:*⥰-gR~T.a RoҨ:iTs47CYKs܎~tsDZcfO#5zAt]i{ZN{<s' q8/'#U).? rq1ܸTFO*{VpOS 4sޒ7*EB*R*jUN O@Ms>4&Rz ʨV+s`_q107c1 "2g!㚐dr*94l R*]hMMh]} O9cT gBc;j6O"ndrUxCsR+XqR|MmiA|d_07FR\ga5 1eVr\Xj:7KAjQ}|({gmMPp2;t[U`(d|C5xVU|SBe|:*HTѷ tejQῖFZ>у%-=9˅{uwS=8.J`XA< joCL5ru-z)#UXF? T 4[svE5G>HB*iH$.!OZz}8;9(#dJ6:@=vڕp >m`tz㌎ZAfRe>¡ @$y2uPea::Ք N:U4=j~DT>Z8;!kE@uNi)Rz砨dq֣w늫\kd<`ҳqۧO^;Hq }*V% ϽVW&6}iǏR>2i\T)s2P+KLILgSImJvkCiأ{Zʭx3 T9+?h ؚbF- p_ۘfr|&6(A]l&=y␌Sހ>N'( ;<JooH,4g8-<6rzJd@&GqM:w8KbXG Fp}GP[k7(%tvO\EUœt瞵؏Z2*EQd*8|Ė3ꧠdN8&In֗HSҀxj H3RM +0;REp~}" jwdU2T\z=e R:R9?Q@ җ0#qӚk69a9E1#=DSq69ۜg5"ߥW\rqTf|8Jz}+916Mq5J(r.E.POosZ#U[R~aj:o; ڶ27s58{sysQ2Hѩtɧ K$.`S:Ƽ֢{G=[G1syrIY"=)=jGj󞘧$59I>W.2qMrIk ;gڮ.*-;:~ua%Sǎ_zZsYdԁ ufG0˚P+A+'ڠSn,m`Afx= .밞 tk3ue *9xm=̌8 T I\v>)"n2xc<IbϵbL6VdO.IOr&pNM:&›I@{ @nZ܆_j~FζCcҴa<;9VM ٝHc4ABjACTPqP*l5sS)%DZBԲrZOIH?X{cҩs@4V&'Ux bG8&n3FZVnBsҶxv׊Է?JϵR{N+H Wt(+U=+D2xSZ: ׎REScj@=?0c!ojcs)=Nj6868]zPsPcy7[n*7 5:qR.DU|TRN1*s.bך3$jVnD9M!J->5pAf6YI$כG^1z5,ޤ=~n+ {ɶ̥2D'gMI؟jh0Bt8R؍.ɥ{U'L$T./4o^+*vٽWY W JnRE>{ΧWXZЅ|Ƃ6G=*d<#tɩ)W1z90x1N1%& j̈́ԌJ㞵 5jE*܃ qkϓN*i .מ6[#PUc9;[= ]B@氞gzl޵OD̀pkճ׼.$P<)M:pLgHtŒi#5YLqӜUp'ֵ ϝs<#9Ty&eߥ6U4~ѕ(Lx]]]Hn3ޡ8Uڍ4OҢUz־ƜDUN?us߽irCdp:ԡN:ˆ'561֬"4@Fpj6S7Qh"N*86j LA)sרDÜJF"z4ǭ'1I(7"aOcқSʡq1Uސ3H\mrvqت+QּK@^En+|dnXӅ4fZ%;٭;Ȭs^v &x>Sl'I9,rVeáM":ay2dS5ThYr3F06՗пVGa=+sY gR@&z>{Zt}̞1@|[(/QC)1XiM${L!'I|& 'FќץrXvܚ@OzTF%偮zWO~>& W=X&3QfFyқB;R M<4K:xTsRLA\zӇ4;4F}E RD2Jp<{9"LLֆ#5aކ9բE49t+JfO!\Bi;i  CdfJ+ :.Fzք7]9R9 ^b=O֮Et}Z"9܁qEtryCtqְJ{p4'f\LFME-^x3ϚW ;dܿZ<*&%Q0  9HrP s ֶtReFv6Oj:3e'#o?Qw5Qr1צ۝3Rj _*àʩ*cEiƫLzT95U 3U%jP0{ppz8A3xFwc;uAbV`OzρNɭ;`8˰UUbiN*NjtPu>5"{+*A?ƨcZFRR}h=B͜ Uwnubc%KggsVN9$OҫK/&ߡ2yR'"ĒY2s׎Ӧ ͹'%V&m'E&Fyk61zוF*ГR\Sձuj>,lHSjD4 Uvmcڶ9g@1ZnsZp`~e,~Bt>bD*Gg>ӎiܥ"pi۹UTFLOda,Ꮽ e*σ5e;= PFw=\թLѶZ֧'ml+fxZ'rYj\PC;sWbLp:V4L ?J2کF0OziD ']Á֪J8hLɟR֬Tg@dtj_1Uw^1VFR2#y>NLK!J)ԱR{X߿ENc+ry/ ~UZՎ拀x7>FqL<.KJ>y1<ԷbgSgަl*3Yje^FOބ3O^HɀNF1QdIA}D?㿥0ja w4ܞ(# ?]KriM#tN3O͜ )Z.Rc ֑+qКcOuS&I8ژv>`gi9{P221MI1 QqS7T-PI7y0UP@c|:F1ԳeǠſz[)"Vusʱ[ӥ?4njWFqH# :WzWU %FySӞ m^/H|3v\H oՍQ5EV'W=7Zm aM'74զCB F: OLbjCE4Lg5L?lz&&L\g=i7T9fK;vi A4~4^Ӂ>FEK*+֬w&Fj6c푊ϸd'#Z`҃ZG$')jXc5 EV^-c>Af9sQ=6xU Ѭcs [*kx6 V>4۱j9 WGdā湻(7V@QsX1a8=+: r0׊DXvATgn1RI&HsIqڛe"A<㚪?JVWrM$qsPJ:dV|ץg$Db8 hNAJE9a"Ig6Vܜ2kF>YxY`=+a RylJ{S-V#Jk*5w'P8c4iB~Pz$H_5(~:UjE^Ÿӑz$m\63})SbFATçCTSGל܋6?Ƨ8nZpsS+<J*㷎=W,o;gʘ͎M3qқyM8Ni`9y8KbdPhn=i24sq%~'z'ƒCާ.5!ہ?LR.sJQM2nirx$LҮFNjԋL&y?Fs+zrԀ}sQi9}#U\1X}injaji&F9ϰR|W-2#!TS2N=;TL19X⁑A튍R9<H_T{zU`[1p)Fݱc)ޠ$HZy4␇v~H:R܍NjgecHIWFe mYV_9T!pݏzƚdfSƳ=>.$ɁUiHq>bCſZѕ@QG"Al8U⹪M=ȯҭExZ%=Ź-][wCnYG~); ƚnN#{ n=jb7n:b`p!3N9=aIޔ֙Dw lc[wr :w% ~Uގuna^k: VFk1XCҎM'zp+⛞怰ԹE7SLV% An=-ؤ-T& wLAf:ў('j;v挊hFԌxEۭ854E0n(j$RV,\L3FkKd1fbj+UK-, Ejǧ)r VɁMkR:>ÑӯC- I24kZ׃Vd+'1bn8&Q"q֫DjZs4͊MX?z03W`r(n[-c~4m~5Uq`A4ZW:0=J(Re5ttDcp:vYLc5ʹ*g811!c?ҪFq֬q~U@ZVgN 2/brsYRCֳa$g(R8 (+Fd?B}j1Jţ @ϑj"1V%x!nm=9i.ArjE>K)X9 Ք?J9a$~I8F{c1*_0iE=Ϧ)خS>:M}l6zn-FY ^~cֶ4w>՜d=& `l 5wZ,E'-ƫAP/\*o@1qZq&ޖL0ۙ#5w#qgz&I65Ĺ98>+ەg$QOQIpylgdsQwG#ߎ9ZM>!:WW'fI(\r})ӷ; o \`crQ֜9hn:SL!JNI=֑zd S֮C0=zqZeTl98'F4R!)f.x L/rxL!:.cu w4ۅ=j= FH{1~W=XDj6 ؚ\b京ӵs .;bS`}+7HhXLN˸0#^r $PjDTl薱 '0Nj#ǥ[MIԺFOZ֒ŤPcFaJ,X+/5>U)Rտ$R{c"\,+)Sq5U`=ϭ5=֯PGTrcΙח*K_ֵvv״R:u[vq]"9q>wQH23V/Fe~M&V^Vr&=rtOHAz$9eOҩM)RIT擾y74p} HͲ A)?a1Ht>y&P2o=xQvb7ۆ*y⡐qڸ^LMRFx8PGSА8dZV>~`<RD9$HV-dtJwb3d- ƕr=34xEjEFSws!C}3L$wFqIԟzD93׊<.HJ#8vZ0_H^'C,?š)=}(Bcvp>1<.Ny۽?o)rtQiRjr6j3*Fب#.`:{׃Mn|iyҫ!zR#ҡ݁ޚ_1)qQ>6 ]5LjcIrZ'=4n8=+DS= rj"UEP1y8Q73TGL΀tóޤ^y眚?a;r8(QӊQQT,;\TQ 9Þ)^qi:35/jG Zh)6?t~=[[\8Of>Un;c'5&#^:WG1kRK~}x.0:9nM0.8ɪRW{T$>z48@A(oJ8&ƚOhji9B}iޔHMOFiHjhx<ޢ&4XI)KH8)iG4bOZ@)Êjc TqKRr*,v)@ 5 S!"-S5ڼΠ/zӠg<-tu pEI,H@c[ewsZE64bõ3zWI.8ϭw@# pZ#` n:a+9[UÌig^vC,R9Pi& #;-#T[qǭHvҫNjWzS )}O_j0׭_<*?Rga( Up7{Vv*c?Q9!KD.cbA+BԀ:RJԴKǭKg8#eNd$SSaKcJŹzقBk" 5zIjGmNk>{:֪]\c9nʨIsf%I5U&NyLx rjc4sޢ'׭&HbF3Q7J{u!#l)>c>7m5!qҁ=F=h >*008D랕I N-8\|8s5:)\{' j[Y8ZOz#֩M;DZk)9Ȫ2<6 6zdV}Bʫr3'՛5N=W{S쎇 ^pj8lknivTGz5b 5F1S ہ jE:{t9=r)y0΢u=BIJiNVI H[Gzv==i^Dl3j-V%x>\cZDU݅H}Pi ߽+˪x➭Tsz2?Sbq֞}*COG^9˨sϭ8pN]֥9NR8}(|cD$nbay_ƙ?KAQsVs5GҸ@ϧ֣ctZj9?1Z4^4r8i= aLBzֈ,L {;cޚZfȁ^j6ާaQQ \,S۞{rxϽ(OҐUXH~qc%91L1W5E&3.3MGVEjMqR֞SԄhp3ڔ94pzҷ^8blR^H4gJc߭Iԝց6)s@9fa`RЙY"}F LV5;tGZۺW=OPs֯T$yi8oCb+G~{1Tf֘ja*AT4 qTC:R晚ZV3cɭcc&+2x Q+>u Ƨ{>X7[j1==g#]##¸w9dҹfd)*cMۓZ06NiY9e -@H3N :UH4Ylbe"OZO8U Փ"hfrqyU|9BqMOJ@66({PqߚSZ:MuM8V@=VnV-ԳvUֵ0T݂#no. {VHiRMjdW/]:*A'QQԁ'F@5gUgm.?*n%>+R؃˃qZv+LԷjr9qYq󫑒F?RZ sJ 3׭dǐ@_Z(֊L 'Nx߁SP"dpj_itI4 jsI~YgUʏ3`d~;F^GLޕtz9u+IMUKbeYy<jpÞݺVućy ؖT^3SHFrj"FqSq ҐON{ԣqR*dghhG1LxeOU83ڳVM7 ?T̼e@IINϜѓJȏ7^8'֮_&[Za zzSH>֟piSb'$Zq &UR*`/zb5n}GLP-S?ZÏV ֦Cii۸+zM냞V-INJiU@泔Lڱ=j7Gk:'GBzԐ[R)8WE;> ߯}齸; cL DR/#D8Xfҡҩ&h!+n]xR<IFD;q략.{t!s׏J cVoT1QW ZaLSL"Gq'\c$TR*\` rŎqޭ^h"G*UL(> ֜ c*Џ<p';b ޗ,9(3Hv(yXG}{+,W,!3gԂ'^?^ZdP$tH/N)UP>Z /zNi⓽)GP)HTMmL㋱! $gkDG'\4/P|["~}U>1W(w,t&h6qڮC!n{VlKաןʝF:qt8 bBօО2Uxս c%A֝#ΤL[aqY0JF֐\Iq!$:E"`~ޢ2}qUY2 Rcdvg=zQ"E:g(&sR`yH R4EA^*loR2=i2hpy؉"x\z32GUS n{FV. ?<7#'ީ9Jaذ*=N=Z]V)DHisL 8fǯfO&ךp\T.1۞ȩTr1J5iF$E=(h 8hO_Zv4cjۿҚSm\t`䊲JsH(N V})D cO iA-156AJ] +0>ZWvy2sV E6JH c r#sM" *h!SԚd(U 5 /o&~uq -lX 8=c=_4f5 vuB0 Ԃ&XkZ6R1S&TGW0JԯJhJSڸqs5sxMQVch )g9h]v %۹e TIY1QHۍ$䭡cFM;baisSҚhݓJ q@\qlSᝣpT4;FzGs#qi]8+Uyu.ÞyUYDWVFS<ƹYE{+=46f[ǞEE#ҭESJ"8aک۞0ZczSEG^?AqZ[֨dʣҝTA& .HH,iKTN sUI*gl1$Rh foVzT.=*YjyVd*&U뚡6zj)89Rf_SN@}sԱ2;׭9TҜ@1ZztB352ڀp,bY UzRl;_ኯbˁǡ.f%?j̺99l朊_U󞸧7f9^K zR%3OZhJ( SlS? cނ1?\J/.1M{҃R.:⓯)~g֦ةz{z 1R'-pj1ʥZ-9 tzuX6$mlު%EٝtRP[h #LN֮b&^UVL~^SyB9=]`̺nm 謌>u1y]>rM8uQ8Y\FHͷB:h\G 䁻r:u &Hlb˱0Ngީ)*mwaoެD29MUέF1ԉ$ښèsR:z"qɪ֓( T'C@fȟP:sWBz*M2+Nq47AS` 32*5zՠQUcАTh>@3}j% =)H#'@ w'bK3s֡Ɯ ?-"E5"Bd}jH4I$iN7Tm()?Jrw$jŌ#Np8*EC#D2;SJ`N1tw+?4r?YTtXVIFLՑB)|zS)qޔ'oZg z34\Sb1;i={U;t2H 䚞G:V^?T6c6QjSYS]6XCgs@t2ǹpbwP:(1O}}i;tQANw;Rdh͖?AKJbjҗ~Lp95f栍rv$^*jգjeqҩ01Ͻ9fNhwa(0&qh sױj錴=Jn萶?ǭA34:UYsc*ܶ Cf\NGְ=E-H$٬YhX0\Ab?Y֌d' ޱ>Kg&XNVeR7:fh=;;afcnrNK nipylW2<j_=C:Ȧfw݅Yt8l,sS%nqʎك.WUOq~gNvRzT8fѲ0'3Qnϸ56G}(ۥD19\tqUgQ1VJHRej'}*/bjO}j@x6A"OSMVK f@f9x_oS3VOr,)4?NIϭ>Jh!'uϵ!9*R%^xHr*njT?0J:4cs3qS'Bv1&P3?ǵL՛$^{dR9T5QE7`T~g"$xH"4Lu9.V-lZvoץ]EP')Cj) `tQ_i!R=x81zu + hQZF~Xd8ivqOIr)GHSOu2nj#ӁVY1+?C3M+sR%p)`beҘe^Nt1h9}hLtt$zNJ/RךD㊬[`jcqM9q9釡h5 D~ȘҡcOPj,V9Z:rr=j*L߲S֬9 (A^C;>tr jܱk&Qf30/8eҀ+[E\Ԋ;o`? #ڟp^=M.tc14qҜGQڐȘSYiEA{c֣=L>R5#Ҙ!i@zWqC3d$dgHi4#9!HOC$*EQzI(4qңp4NWSG19kXhM nF ? zW]:ɢDu*bBIy?`\_$cZ@5W` v)@0$P8bSϥUNe(E+*S |AurʨvqOJ}nr۞>+o43>,lǥvB *r!+)YǁV!]_zeqɦk1xrPsEJ Y%l"ʺHtAҦ[qqYJ8fi!r#$Jldn91ScPxxt Z<~n^CLs}vǰhy'oً۪7 gNexZҵ{~UbJbĸTp91?*3,G ʠAN{z)2cDvEgD"#ЊL҈fDJ4.zRңFf'ֆ bۈV|qM~ 7~Bv[R}*X{I$p[4Ǝ×Ap2y_?JMC6WҴNǡIYg*<`qU~=OZe+ٕQ@ǵyֽv9zi\(KZ>%*B@oCdB8UsN}O3 ~ZnZXl;byj`PExHT=EZT)׾(j%&N4W X,=z.(zjǒsj`bz{Rc'ޭ24`qvj0>*r@XRc޴H"4BZcSq=jefH5#@qSsN5*ZCG?N}PL@?/JF{U]N4 A<'C>m(N>Ƒ\0X+8hHIyzT ;Jn!N;Ս7ns&g{? W!_LԽSe r'j׀J4=sSqRQ@| 3V1sO@dU!UfN*ySp[jR`5v~=T| ͐8*6u#zPDvMN}jjn&C!5 >'ZzVflzsirk2>HiZqNLط'*i#T6"gڑߓ5ܞ!ͺ}*9N' :SH)9P Мt➩{T8P4Fڗf9N4 Sa_Z$N yS? aL_zc +Q֭2g9FS@j2E;ez`MD'='u搊 :y;K+00sQI2xIECǽ.iPjY,֜;SK"קJbxJ4;I&Eӵ(5&i6bUeY 8=)9ϵI^%acTJx%WU=)#0;p?Gҡ!::hi -۞:i0}j#_^W汊f:X(<-^h=*~>D80$U t=i@LJ[)EYQVU3ū׽T`߽/TNNM-X*Uo^Z#ؐ`A1ny5,/OHe??fY]zb0Q9"+QL|Tg=NS7Q-ĜXUQJ@s3^P4ԃn:(r3֙Dy㚱UElh(ƨqϥYp{.#gTSUUS P2JBI|'8 Ҡv'ړs>BO~DhV*1R>8 fJ?VfGʠ^883gjԅ)})P0JI>sNA)N(]gokJ׻ v[#f9jQJ?JڜP3N)8sH=)å$;u=M恎Κ .}) 07~{԰ ⓓ֏Z;qE7?Rh.H95j%bB=jf%tq7c)1c;ҳq"0ȫ@{Ncc&)/'W qWά=)tSQ<[Wo$\?Z)%F~EdWdu&FL}$VzͿ&沜lg)(yю8% Ri iȥ=i8 @J\b NH \uj^:r* ҋka=i֙?JH 0zILzUe ܚba^em:X&)`:>_ܠh3Bj}i:N"^E^O9?&1M"/?ҥ (UZS׊"*WiUxcRqUaێs5YFtHƂ9mgFε0HW'V AJpGj'!EU(G֣e0ǵC'^EV\TR-Zn? G fq'>BNQBǯ_O!5^Nҡ /{*Z2ÆS?:1Np1R*׃Wnݾ4ɪۭ$f1P7\wPzjHcZSޞw9z,ϥF<ӛCЉV٬8U3zVGW]zu&?-K>9pF:ʣ-?qQ횞5$JglԊ8҅>*j6) ڂRN+H4}3V6cANBi9e9Mݘ<ҚcEƊ S6c>b7L ;P:EHjǵ&&QuN_ơ`:c6BE4ԄSqT}Ij@(bbH)iT2XOZh栆9zš@A,M)j@8/r(=Tl?Uc``gڤ OziSS7 oSJB#-S44|R.(tI($8EU2EYJ氖-3} 5 O5- ⫱$Ԭr=괌93Ul«ձߏj\0 '8Qؖ Z^hV]*1m`MN*ۥX\~_JӐ>^HUU|wmH".H;V4gVVRHB OsTQN Ws~#~}ӗߧ1g=.3IKjUbE\ҥ='9RqiNtH@if=N*9&湪KԌsJ"|>sI\~^]Dϓ78E1BNf8$\3Ry9YNII@x4'C`i1֤Wrv!ؼ@:C׭Vɭ3({m'8L(zV3ƶZz8qUn?Zplب4PU#d"A^qZoJq{CH%2g<΢CǽLڋ@{ҕOJ:Jx4DArN(PITNUBčTR+HT:5SPҧA \ r9@nʚ)+ޜ@OemqR֞ӎipiES"MQpjTh*s=Wu犤0Ҳ҂ xܢ&_njV霌2)H╀MN.0;(r;T/Tsғ 5\T犅pjBBcT!v]T}ji EDE!3ZT ?VSq"D뚑WBN1Rzh*A}j@:~zq֒ΙGASzSt޴ g![)nz.&ޣh@z<E!C"| ҢuԸ wa{Sϊx cif;$Aaʚ_l.N)嗑UCqF{.:n:zI'eIjIr{L=yp.9'/34;4ޠRG'i9DH&3ӧZWo="޼{Tc=yӘnHiyCvYNq ZN&^6l8)&ݰU&cG!ڄ87>VJ9{w\Yؓt[@O85d,gWqRC1;S<@qlpoZaրA-!"8)lKvH@I$=)iѣH@QUl-mn8" D30f'ڤH*`;P5bTJ=3UfV:HRbNRm&J25"0ֳceFzUؒ*˭Ns Kjq)ӚV,7ZcphNZ>6Z,(JGԚ3y(h`pwjzsG4ZՂu9RZE5aF?QRj=@OO"S(nR8 erRjrh`3ҤNib+K<SSF3Z=;SL )SQg}*PH])Ͻ gHy!L>8c6MC'=*Y8PH DB㊁_^՛b"&849sT.#h,BZ &Ny&D9yYSnfZ7jW-Vܖh^mGģZ[=SDÏAWnW:UVlW {Uj{䨄#\f(4jrGNՃf8NU:SmzS0ďZH`J*pAN\,C4A6>18+AI!e;OvJ&?"ʌL001[qҢ2z3ҝR=*='N *~T&&Wz*Z3֪H8 Z_x *mF}h D):T=jHcTqڞӂbЖ qHj5?$CN ;ZFi6+O^*݇zCc1zi3V1*(*/6! 8q9NzT^d; gN~*&ǮIRŒ^3ު5;!5xEr!ҚR|$aT7ÏQ3=3 @q@yd8) tʚ4 =P?ʚ͑SpQZ4F͞M#gZ@9P9\Gz.y뚀jXtn#z vcN$zbAӃVuߦj?'d6r*YFdݶUzӧ|沑=w4U@n)P4> );R=i!&1A9;@Z`/J}7 q8q}M)Gz0)-EƮqJr ?Jvc`-ZV P0!#ڴjYZ؅4mjEnY: @+U?N&DrTsҫr=je?e"sV=E teZWNU"8r:94=r=S?JJqzbR/^HȴO^qS'n94ti2'8`\{҂;sN&;ҞZwhIh<2AQD{RQgߊ8"dvGޗ_2G֪ylU9RJiS9V ֨'zyA{qYI4ll0ERg4~~^Fϥ3&ƻ?R1'!5Nnj2z%?^i3ǵ#AdӔzgAڜ)eջo29h\ǵiHf=9W`uGc1n,'Z)Y.D،/>n>85]'Z>P"1迉/TcsM 0~ԡ1<Z~;SCIKcΤP0uKަBSSmBscV)ךcU>_Uޫ2[uZ'N:*“9zZ/##֩2(Jlsꬃ9ϭZj:C+H:fVq֡ayjd@ӊ&1"=;QR`(^i*E\[%&HXD:SJ2;i:ʬj{T0D.i֤ͤ<ㄚ z̡iA@(.^`wq1Ͳ2*aQ\6v)S]qI7X2pO۞NY8K?CZgsǽF_ZkfN+̓~q/ǭFNO!MQITٸl`n}tdNH'4@>3Sv]>2c+ ϵ]yR>f3m lU[Jӟ+r VCO H[?3ShAaOғE9TC #RrXɩDM]Cdb#~uu:çlRe8S#1VTFq-YaH p~\35qw4DשQ/?JzDeI;JzsLGZ4R)/TU$ 7~BKL9'=(K\LZ@q҅4z~uWwgqjJ.?ZC׎ԭީlv8╸ #bLҳqQ?ΦOcB;s7㊛U%lԒ?j桱=MTGJ}'<ڜJHC𨚤b*<ԶKO_Jnh'5 1y^M74h!'LUQU$j2Y+^r֫(jn5IEgHiHR؂4 iۮjk?i@0:J?)Î*DJTV !Rm9P@R ?=BҜ@O\CjCQ! ~O4Adwǩ~r^zUIst5F^I^ ǥQg$e" #֬,_(⵱1P'Ң> `~0#;P~psֲ b1U .@:ŭM =iZv8 c~;⺔tE܋k }jA'Lck؈֛NhǾi$ui@''QSs3Fy@ ~ SJD:Ҥ{ ~JK ڃ.:u婥hf=:K;'JB$/1S S!4>:ty1-'Nޫ qҦ ǿX:e[S9V&1(=Y vs9})ژ,ުLjXGߟI<7J3ɩ%IV|p@SJUM;튬>Cl { HC734"16<џ]4WM+HϵflByzONJPyCc֤^G=i9v42[$UUzO^LiKf; u~* `6`~5mlzWT$ϜUY'zU9Jp8km?h@=X%@?h< YA֝)O^{i}#?ʩ1ϭ.SqR^;xWI㚍<t眞Ҥ>*'=jr2}jÊ Nr )Z {>3ҩ2YNN 괞I߷UfJ6@i#5){Tl?ZTgڤ0֜?&fǡPsf@ LxK )B4:V`L*VeHI#ǽ@ OULSA뚴#``D6VH;sR*wsSsJ.qd v支o֤8t1zv XxTQ gޭ ~+(ͲdPG5:.[PuSqҶDqpAN18>~+T=+?6=GZ նszSHzT:j&^5 S gjÚی!^4) {D1*79&j6z`ML{7@;T\$ JC错*ۯH; ؚv.2P#֥Rp: ¦CzPZ'EJ_֢C=EL=I"ϭJ?CϱѢC;`,j sO=617ڞF){(=)Wqe8#'K2׸\sVU5#H<ԤfG)U8n2*ʀz^ɳ'Q"8Տ8?NMR[?n{tTY4l *tu%P<Q'I T7[[PHW-xE * e*=U'Zke~Į=;|l*° =}ϓ7PFzUoe 4`Zjiu0*E+"wҽEo^qڥ UE=XS-26gJzj@}ZITs 9>n=N3ZFFR+w:)R^մerOjz @<~U)ϥ;wL!w'>e&Jczzvi8Jyb3֢w9㩢(Rd֡g&+^^NNiJ?URYx4s YU%C$5v=C`=K({Lj )6+)*c<}ic#Tss֐"&L⦕*Od37= Ǹ%?ʪcdlg)p1jZVR>J ڋC^If7=V֐ T95bcqޫ?OAA j0#fnkDɱ/9o֭=*6})_P)s?:j,.F)꼊UqRT_¬ 8*J͙0KnM[vzi3vWOMɔ3R` tޜ?Ke{T'y6?Jdd~F>=Qd)7VNJK,/Ƣn*I"8J- pkN( \U/ޮ0u_Be5iGwjbvO4zQy%!rGCU y4!49?'#*[ $zq\v$Mh\Q /֪<&$}r*KBҭ[HU-FL\tDĞ<*h@sO 3=~͋jjAvP$TGSǭ^N֗8\SHt :~O=)2O ;X1y{N#Π2}jdZCj]+o_z3;iWۚ~+BFkNEȟrOjd 8ۚMB$ThG992UQ\#pNeĜZV2TsdF ӶdUh1f08iesJ58eڱ^+J5RfxW⒱|jI׾kdaQXA g֯yj{ *yMs|Ol"f5wMYqq䎜kS!x#=jYRxҳT&.EKq>^Ԕl@qQmc zR"n(zIڔF) 0ci_3f BRsFGzNH^ZP1sJ)P&?4Q֑6Nއ_ :R暧#OLwjE R)TYd|>Z?adޥb8q֜R<*APH1SʤJ=b¤jXQIpS@B9;օ^Z?hZG=ZGqR@#qQ>\ӝ{vD%>bqYsϓYc* vǨNL&ll~0xTՒH\a%Ԫ~\JQ5,`L6lZ'N-.xr;zUn:uN1yl9PNO^Ԅ=;TOfЈ'Uz*!ګ08RxQ9^(ds)̣TL2}Vryp94TaT.=HN>]$I^EQsSr)"Xϵ;Қ)8 8=3LS*TPٛ? 1s@~=jIAR*]G?Υ8q:Уs/ nGlu8i2qҐ9$ `Ү@3ۧU&@JJ.ģ*¯(}MN8J X$\^1dci늫kq23סP0㿥XN80.Q2jϺ\u}sT/ #'LMl]3X]NkeϘ⫞ҬJ9s\1Ij;=hhE1RiqB#Hr}?*o0=Ou$n:7 ަǚ?7)R$c)>wi`=M nx(ذ9QdhY@|5%+KK a+$}jZQ֯8j18w(:͸9U~fLrO4'pY!gYOU\Ew>sSH;TnCd wA,⫺{U9P36SexcXsqPj,Lqӊ1NI?JN)3~_Z oJb"xd1q``c82)Ҧ䈉Qy>4ϵJAڡ#ف;h+v4NFz{VlH In5 p>~׽eOJo&WVԧf&h=MNV8F3N?i踮r$\*"Wd0qUĩ U.T$ʯȹBszH'<-xާb]1ǿ6\L=j/޵qmL]@fJ(USRWڔ/6*.q[U)Fjb1OٻJ:q&DM<U[[+T[s1Q)ƽ3V=N`ja8ǽ.R`jNxW 1#Jzvss+ X3Us4RlkOQ֣ sV$ LS\Ъ&t6j8~㑓ֵ'thw50EC-OZXfM6MO<`Z;}$[$sڰ5 QI#5"<2dY'ߵ8yS?$Y?LnG4pM4)8!ҾXd>I4fF{\iif+ޔQA6ނ%vdR&JvxN9N>}j<ڤjF9Ұ7}"ޣ}hoZkVK&j`}j!ӊ\ Ԗny:zx"Z&"\qߚk;èOUAFGSC$ M2*j3 sL#`[{:vMցҡɱL(*3B}q2>աw/\bPH2O5ҤC5(LZE*EXqTXH#aڵ8r09[D+վ=jך=T끂;WԢ}GMWBBҬD}H ǥ[8UB槏=8Q-H(P+zRbj!9{晞ZRFZd;c Q\L@4\BE# ot=C]4rN3ֳifRg>Y}Ңw@b&2iJEFfڪ.&KVłvL ~X =㱤풜sE@UzR:C+qT'[{ArrF\u}*rys65JV7 8*VdNq@[zӘ砨֥&GJZ?h2n/QjJQ?ZL74x< lXN 9j_5 XV㊝q?WSSGz}*$n48uKVZ H Nեm' pG|q[E"'B* 8$8Rn>ҍV0~AfRrGNEL_ cH};TEǭq;rO*0UUb𩑹Y[#iї1Z^wyaXGRj;DA1jص3u9zg5>7rpǿz~a^XQV+TV~ޟ!*%+ )fLB&d!qEH4-'ZZ()1(P4%))Z):P(E8ZoJZB)3;8R`S0\T<hZ^r@)l.(N±)lqNGUX4U[i8y<ũZ\ ̥'4ƧQ2@aGZ`Zp`yVByy(l҃` 8dR0sgRHI9K8M$ *?JP;Ux<cڤYV?zU%Q17 bZ^Pp}kFb9tEIi V@()8@⼉ݎ&VHOJn *rScکr8b3@]#ч8Xd֬FzqVj<'cocHV)uz{ROG['sH3o.2zucONykϞ':y58..Nmf3\- i$9*bњ,G16M5944O̸WO5n8⺍8ȭM 9aqU`~LǎrIuG+dwRֶ*1֣##L=q1 {H~1*dRn{ԈR "<⬢g8"sSx3`=*eR52+&ݣ`3c'<zSN_CLdb{Ս')?J8 9cW6=j<AL V qk.#}+UH)ӑ^Z#jx={$dΞ>Se9Y=>VᱞqZɌu.3}69?\Wn<~e^n"zYxV\W.ߊrkΛ4Ly╛LciQZn}X֘N~CB4`SzUD"RmZ~tNzpYv[5܌0xOs?_jзIIFY",mxו!*Fkbdqg$Q87:z5i6>1J,=O:ً3>M5?*4=rGGt41: VW㊯y-/ӳ"0)UQ9Jrw'e^{78ګKlўA#Z/r68O0=kHexP.[[ƢG}fl۲=ki8}kX-ZzLw}iWSnF%= h5?bpԦL/V㓞jRLs\ҕ0ґM=*P֓Z 0% S{Sr8;=8z DtSi&)( (k9=?Ȩ%S R(%V~bSU#񨚞ǚaQbF֌ bu/֓ΜiL֜P2jE=\qSƼP@=" ]p:dbGQ8 ze9J"O4cB>{d0 EHLv#+A⳯,ح)Cn35R9VY0\T{JkG`{wy#?0j}:pjJzX#VPtђ9ެxkNҞ1ɦ(Ȧ;RƃST P؁H*@'==iy"39Bsj`A *DEۚ sJ/8altUێdY}i<oNDl~Tƈ}>)b$Ph{TFr?jOʢA<1AEқxW.3Lfl#U~`FA^שfmXjuCӵ*)G ֡\Sx49j n~ʀpGLbHBg=1ێ `tp0z{H<)X,W1]* gM^G B˞x{ҰX-ЌsY|1z3WnvCeFqޞ1қlڽ:rдC#`VuܼN;ջ b^KqV= OXwrd:w9VMԄּڳ*\6X{Ry5UۮMaM,5fO$S7v[(ri['UXSZAUSՅiʇߟ󪧱7!'f6ԒڱL>Y991;i4Ob?J+3ڱsQ5'M=ϽLCI5e?VM3 ngL{{e?V~Bش?zpqUezq[#!s*tGGSj:YդSIT&NjQR;Tu1t}*Hoj!T~*AQ?5)*'DD*WQ i?LiDoJ)RRQ :'^h@A7iSRMTԙ'ATtZ)ch`QE8!@)SGJp"b_ZCKHZZEKHZ?֐ qƚ:R~bӏAM)Ҟ:88*UkaA֡ 9=*hzAd<SIOTX=iMMP!ց@@˺ykէ<ׯֽZ}  1?ҫXJb*-8}M_>Nv(<œC:4ԝzTQ/ݩ#,7?NO\~RmXfnz޵~5s{ry=E`ܓ޷n+~A2u suZFJSiMQV>ҪEUR qoړɮ~Ӡߵ~TΊe'z5+O5(Ю~UdZ~*?VZaZ^d/Zhkbǯ֪ufnZ֛)!Q**R҄b);~!R/Zu*EHzԃG響ZL }*xPEGSEO8jh "QGxֺ0'ssYDp}+A~~5sLW%pu?J/?c1Grr>1XB<oWb'b{Q}*OMKdqVUvVRe8WI{ΐ}JS?'޲{rrF})uNsQH:iƐ”iJ`M=S{H@zcT-L3z):~?ʢ QE*Q΢Zf2p'ӛ44j"9x _B…Q9$S0CƧo? zҙ)_JD0j OZz5jz{ZN֢"^?\^߇5Mz#]?zRSkԧ.zs[W¿߇l 'Y9&;Yr5pEI:~]X~V~q(<*{JgVȡ:SC΁hV!x}¬}MQ2 4h8!(egift-0.2.0/testdata/src.png000066400000000000000000001620651513354670200155700ustar00rootroot00000000000000PNG  IHDRxԅOsRGBgAMA a pHYsodtEXtSoftwarepaint.net 4.0.10 IDATx^Dtwvfgfg&M-۲eedffsq:;pݽ wvgo~<=U'~zdn#?>?=?"x6|6r6x1p)w9t-|tr5tjձʓgr+斟M9|29LJk )7%_tV⍛o%_znČ)Yq9qyw J o,)ZZxBEsk*4T_E6ޣ`XL)WDɗ R\)Wr+Tr R˯vCv.|jQS,YFϦ峨y4rM!d$\&M'(Elj1Q.dW"nW%׊Apk:p"~">BkpCxH.Ard|&C_ ko껿\ZQHCʒOc [hxƫ "'OmNWcUQIbTF!ql ]fV=A%gUT'W&8ho8=61O>M{,OୟgН_K:腜s]ʹv>2.Mx> ,{:E\f%'$Ԝ2sgf:}&)OEgf$JJjrY7ro,- TVxbe 5/W\nGܣl!9OL+ыR Jé5Z$n X3ѧVFVy"v)U ģiJ 0Hy,J!R¡zY-fJ8u\Ư ?DFI$@&)` ">EqX΢Z&\o'/:})4Y%[VC #PpD|9[F"%溾Qi$\ WJ1LZR!16^Z[RUTZHh)dAuNe8>ޯ~~}p{G>:}BYe\8|tSˎn'ވ;xޣɅk7?L;~IJo)HQgsjoe&LO<"9DRSI_$&~p6.ܭ{goƟpf[In'K=v.-|nŢ+ /W^*\]rb] JCզD<%䈨ERzQbUٕn_nM?|8<բhA+$ L,1@tA)(р*J>Z̨0kנ7*xr\o Ob^ DIH#ae"DDPH2!E'JxD!cLĢ#YtA|/Ʀ >d1Lpl21scS/[iZ )j .4+b@'VȥL1W,-M9_=ԫ*Yu5iUvg٥{WOg||,y' Px?;xgoq0w~y'>;uB6p2/._s7o|^+ɟ|zϾ{ܻ篽ցԻdx<碈RRIzA@,:y=cI 'RNNI")ݤӷN݈?y=ԵN^KOH=u \q Uk/Օ^+@T]kߥ4%|bVdkؕZvSp,lY]K;*]1fiA\)92vU)cUɘrvY!X)fHYr\ƪSrZR<B'p.#<$5(+BJLT 1E!(Ed,l,Dh. a/a-zܢϤᳰ,f66u1ܵ5!7&* pPK'Hdr[PǢ }ͣ^ QHD!]_ J*K(-[GӪJe8~xOKs4C?;t9[8|wgO]̾r)k+߿q`BE\D򭢳G}pOO|f?H8yMM.\}fJd|r2=lZ/M?y#+IG/'٥/;r w]wvᔴcY'KV]-/PvZ}5Dud <pJf2ŔBTͪqZ`7v)â^`cj٬Dgc2I4 \ɭVrj\WԾEFƪUp=*.BCMj!Z#€J( t e׳Ca,^N!$*cJ"$"٘XXQ]TVrnn+%rg >T}G;~ǝ?hO}x2+yWn߅ݸy )L1[B+R1*Zo0,&AyTX3rBȪoVQ\jSIvH.%![$hI'l F4%AaѠ6jxHcbN qZFǩ a{{DʑĚxXRbx4pHѰ,&)<wt|ũԊg2N82h7$-<^?M.Vy UDVMID )DA&11BRVfV0 ͢&aCd8eA4yj\d¯jj1ZFR,B(m! B^&$ C'%D S pj>*#"JD2Hz)[Ȑ1RJLQ!f(%,-bD h"lt?}僧CJ!Ddw'{E,|cҐt@$RߚG-Rc4̤"8FѳRnSQ|<)J ш܆ꊄʔڔZdF#%,e+/)Ψ?{<~ϑ_%|E֑yGnTʧ'ŠjZj+FqdĖsҳ 0wn\L8#%99zЙڴܓ$A]-c%T R)ebVB.N:Rjmrm6KElP@7C1Th6h*A!SAԉi5jqo#Nݩ;nXJ–q kшƺ ek5iuYM Lԝ?vTKߩ;MMIVkbTzU3 ]"RJ.fV2 sRNN %-+dLMR1hlv|5 wUY(S1XԨ-jTֈXJiw q7 \I$T3l!>_B.R2 LF-SK`J2,PE &nrH19tsv/D3FNm3rڍWlQS$hm2M DI )"#Z$x`MIB2JHQ-$%4@V@:WhJUѨTRFQ˴j:=lGѮ>J!pdl[ V=-v1pDL S޶J,gUNƗUiM$2 J70ED! ՐϨ˪F6%`3DjRX%gns[0n5Sj5|ZI/epj r2Τ&|[^潏r/$Re)Vz A\Lr5$G-VE0E8i>HHD!II$xJCD2GC2qMsP=4&>$h0 eFM<,'մ>t*{97zu}yx˦m3r3$2 ;Qг}4ʉ.9.#9dlSrUFHHf),|P8s(y . qqr.A% ETs rQ7(FРFj*,:E Vn5ۭ&bmfxl囧_N-znJRNj[?{a7r&Kt,ACѨP\BY^w"h1VB#Cq$\1_J%V8ȸR܂P\,X45&x.D.%b ",\PO($r2ok1ƀSjpiI 7Q%̩™ٕw^_Ϯ_%g-/=RZ@nyjw":.̧2r66_XyQpMA,rP-2|ݢ 8x r+٭"zf $KmQ;LٮGSgcp[j4:,.*JL0[54GIu+5+ηK!&D 64|(P4pWpR.^%!2h zϤ[4bV0in:v:nwkf; ?|tPwbkU ʫGmvMb1 9L2 bXH0E-GIk]%ҳ D(%+pd!KF(q"<G[ jk/ RL++kHLլ3jxLJUN(gTK҂:vv^|'Wnw>ደ`.ŽńO/f#ro#Y VB](^)!DH-` 2 'V50kBjZѦ,ѪԌ#ڮ!=;etUSZ䀎+:^oI[DSmvYfA"&I1!#?cL6b-*[E󀣒R00d*Vj|<D:M+i5Vخ;*Y\vsw7Z}`G(hv}!p{kKp8뵙kЪ:7:ze9l"lF)L$WHo uMNF&::Tf#ˬeRkrTN#V@T|)R9PBTCNCmf]"YD] +H*Z^*Hv(69䒷hHF|8tnZ8.-dn:}gǮ5᫰Cou;ow=Dz͕JzZƴU\cW[SB~Y'9ldOt:!CM4Rj]V"RDQKzǠ"N2@Am7zOhMi޷ 8G3CIa-;V7] S **6 IZ9 xèlq-@KO[s'ꏌOFgƦ&g!-LLLLO OL F7&vN 7ί Q (y)\l[ z-+7"Ќ\.^:8̣Vi@ M|dCf}MrUYBeYB]U !pVgopbhZښ~#qr~:F\T)̮gSr7d/;YXpBI鹒/.^ܬ-w.MbB̀9Ь4$SM Pd%8>]g;:'S@NlnuP=Ѯo,?\ޘ^{^f 7cua À,t̓V,&Z 84P @"p`|LHVKF5aش!3 ;;AÈ D'#Sc3K +3K+ӋK3KSs3%ST&FSC/l.v'bS"~#Dyeߌ<GN]xٍ b@`j*: JZѪjF,5e#ꪒk+Ј<"db+z&G'cSC*ZI ?J['+W 詥ysO+/PV|RYŪ˵E7J㐕 M5I&իRJ%Fm qr :Ұ]+CzQiՎcm`h=V&zsapn-{m'F{]ڰC;AP8-P= bVf٭ {PrU C#SxV ]U)* è: RMotCXoHxܓscUp>62(YX_ Gn<}`&6>;10Z~xf0daߣvoP (:+JKId(V"-r>^-Uʘ5ߦ, uu}pxx1434:?6256\\\Z^ZZ\^ZZ k"dvlruzscGgba+ٌw2-NӨYJC.)dtUrJBQbZ`F:Q+j!pu$\z :pΡ8AP,/ll#-$[ѩQ_VUTյJQ^0FZ EՌl HV'`kU {8DEׁy d_4ASiV|N 2b]F  ݁lwp? vOD@@`7>\ش4`o/N>~huw ~ץa @ {D klb ]ؤx`WJ EڨA 4X wiePXubA궩N`Whlnt|yrfmf~cn@qu _]wW6wV6!z-,΍-!ٰcJ=NӪ4D%W%c%42ZJQ A(@[H[0nk|~CRaptZ%ZƋU/bZ. |WDhF7fbr|lSRTP4-@KأhCݪfۨM*InJAGWqIL> &)a s$x. [K%7dqЅ"\GJ6( [Tq-솱u.>11L{:;V"]+hj$Y,Gsƥc?03г>bH%3VC|ءf `At0V ,l,""Ƃb5IF18C/!iE"xxr6I/ҨJ].*" Y)!JxROtW<Gx.3񏶻bAFcrjj>(6lZ 8+T.G!.VN,j5Ij*0gGͥhBDIQ^QV+)\6iٍjQ/IeEF .v-w-wc@`x%ҷX l l V=hbkqhhwiӵk(`z ?a&n7zVVR `7MGXk" &@SEJKZ E#ЂLQq:۬;^W{`{b0:7241>`uΣݧO<~ :>|:'l p}>de}sayej/&B? ws: 6ܠT4!ېHVk=]wѥDi1;LUͦU5`XF^b%cPUrJo\O*Pz9.,鳆\%ـ7(JQ./U2jə"AMBvh.9 Qf1L"V0ez)NFU1l#C3.ߩQ;dVSa)Z/ Hx5ڿXlDF[#ͱ c.5G'?xxiht3E}0ц]nX(e5y znS#tF=N^11z!kEB1A%"Z-U69pe`dXxȟ>zyO^=|g>}@~ 㗻mY϶n>[4693Ǯ&-V\LprMFdw-Sk ,wwޱxMփXЫsȀ&M,JRS6O˶2&*"f :jVW#(e ݀0BJZVMCYvj.C6ҷAU/v)yV*edL|E !aФn&!̞iQ_ #1V11 3>΁6G@ h3΅k7O^?[8i р-(gN9.A0tfi9u:\ky "^eQL2J(<"L- (gt26m;Z#]#ӱ٭axxS@@Ͽz'/~'/z-%O_z޺7W{ͯ~l>hTpG+M6(1ix:%[#$$!*]Os7Z!BlHdop7yG:l!)]ɥUpr1E,K8&9G>*<*QI)[Tf)BC*QnF *nY"nIKo{UvIk]J]Q&%YbUjNC(96LRQJ6h& mUmXTmt:{n͌,Oo-_YxO^?x / ,o٫o٫O6wf|_}噡@8|&Mm7HAQ@-%@t[RiXtNO::^>^ʦr)3J  ,B Gd8sܭ) Hɚb5K0 I6x.rɟQYXG`}hA#v_4:m{a@n-*I3*FyȬi{fS ]7v,94ط\o4@Qѡ1pc8[8 cw٫}=5#8L-n*Ρ9e#PQbFʇbcCo4H9ͪ`, CŷAdHFnhk6}v"թمkO6v<d@X^}ŗyO嗿fPeWFGF{;"]0(-VKlQ"3MaqlAU6Bti,<=018?5I4HI(bL^q1nDcхHO'zF:cm@K8;]6IТih:lfS_c^0=F_ #pPdm8>44Sv$d4-֦ /6<_Z>K!N[M]S2 N s2^ba ̣FͪռCCf *ؔ4P*]sj(4m.SW/l뙊FFV=^xnX|w }2_~|o1H@Ap}kgq7/}2 ?z2[L}>gcNĢ 4Kh-H\?- OFcх遹hT?*h| #ԧj5u%ݨ( 8El GRM4 aLDѻ>~a-6ӹ-fdx1 !2lZ|WᲴުilX[VHe}{* Y"}ˠvDF"#lNV=#AD~i8FT{LH5Gvv->kvڬYsU4 o u )=lVP&"%dPjS$hIfEȡr[~@[`c| <-O,.?\t̯=95W_W߁^h@|z$퍹_tILLw$ fC2L:AA0j ]#L BjQ`PXda p;;7;srt. Jh\} :Qy^z4rq֥0CȲvuJ"ayV@P@A|NtZᇫ;OvxbmhP[s4\sgm5y*]NHvE3Ѐ0UL"`dfW1J |3pK+Ac x#a}sCep'_Zyl>(_=| '/ޒW߿o /ُ̖+v_}YY?n~r!mtzC͝^Y)lFA6 ^"{%iF[P6K]K`dgzdpa28hPydd&MCInS՗ު-Qw4BI%L43j p9}|KqkFnDǧ7ANb4:;80l-=-v%`-Yis껚 bw3ToL_`x1:a1d@ked lt;SoL?^; Fu;ܑPsn5v:5m6wk"d]bu"*FrUɰ)6?8vVKv]'p{?5580:v҃k)P 3_߼!7@yoɋm>|/^84>e.Z{c;=CllDI4H>2OzVKLΎ/OY홎uMvND3Ź _oLקغDLM"FM5 l ҄:zȍ]ݻ\gy֞St>pv`[s[`MnNͮONO-1; ްi|n$ XUA+El4:iY-J1trt{r|wrl{j|{blkbx?iQmL=Yޞ[Gs遞ɾɾXw`:ub!@jpiVćPRrIJ bIF*hvBD )ۡ<ߦpz}HGhkP8l<]~c Ïi%7~ |Ƞ_=~;;O67wo>\o?V|koPwptvZͺfTmi $qphm&''mggĖf&'?^ߜrQȪxT=d]de<Nmܫe9`HE%hdZ}1-g{ϼ;_ٝOj*|t9nN/.n,ͩ9`$kSKhlj+tymcI٬4fcLrE zk$BPG`< 蘅]16 ߙؚ؞ۜ]ꍴjVF/DGb@,}sѾ@D_Xc+0}^˥ Zz (ƾ,#ti-rEPr_oQ7 c0b7?~54U7`>x ǗQW_+p/=yuNۿrngߦ܄|,v w}.-bhqfA˔K6.,y~2ֿixw`DhKc+kۻ kvvcDmnS5+s/g_PF<'7k_{{{?9;rg]X819;4515:122>{Z.פpjv%Ϧ"A \o7Gۼ#~c^ޘ݂X 3ٍɉup$AkkˣC C# '!tDVknWybXHEJ2K `e$jUN5f 9ǥ{-rh;Bcg6w_wn:'@) 5< ,?Sh| ]Cǯx}m{a7/髝Gn@y߁._+` [JMlqr#h!> >VANd![陎tO vO"=cle  /YWzV㏈A5ߨͿR'װ ϝ{#Go:zPg}N>83w&dS4@wyl|g~iw~y{nikna}jHd/j壻\zE)0)xϮ6$oU:NHOxo@loq1:[٘1=53967mnnlNoLMN, EbӑpHw =cC7[yhA` 2IFLCN3C/߃#$ *SeAh uwN LBtga $ˣ5`y<~񗏞~ʗЈj)(m@m}i~WWw,WfF@ 8ڼVUbqJRjڤ ^EFg4bXx:;;<8?ꚊuN" a:FCқMeQk.0*Tf2=wɟ~x'a9һ=ws ZMñŝ` htoGjo,zAЊ _f d !d`\ <]@hK6>`a}gv 1=2>4:0Xk+48{<6&`zCͲ)RQJ0*e QF3f%îf;B]6C^^X\''<~~ XYB `[4_>xhcWreIgVdx"$Vt[Gí~[E[ \">W 0mLn+N;'{@k|n5Vު/PrQrYv U~]Cn( "4j$EIbUQJo_'w~ٽ_OtھMPGNC~pdkv~{f~czadl::4>005zښ-~kV{kVlr;ͽ7 wzAi2[|>6/l.{t}'[DېLoLN,E}ݡ`cpjBV(m *aMRh-NL6JFNbUܦp gQ(Y&6fy_^tc \jӯCۧ`D `ۧ`2@GyTѧ V..έṊ>]z7;62s7.yI3vWZrE`ѳ5 V#[5v- mL\Mw7#-Ӄc]XG"> Ghd"SdAƔj* 0l#SdȚzp(:?98҃gHOO=k >g|@Wz:-ÝS=c.>953peF:?deՇK >ggfw8Fbs.kq*Ej4, $%$Xoa qZ! d4<&)H.,ᡥ˫V~lZ^}|b`] }V_3["AWo6gd+ b|щH?Ul֋|6u@򃕵GkOַm|(O' DzT/vwnTZ817j4̫ٙhGa4nZ]*]l3Z("ͪH!!q&3<(zs= 8Zx|22pڒۄ*H!AH<] wIUnU#v0{g.Y}8T\5QI_W4HM Yɾ t$6?u}nnY^g7]2}`k7|C=m虍, Nn_Z}`nemx loOEXOYp;J`]cZvh`ɣ]XygMN5iMR3 YJ6@? 8Ǐp`T|F fp&Yl>166-VPxb{?#Wz5h϶o?\[]^^]_ {G)ў]V0u-.9*VG&+X!ͬ V{Ȫ4RO4BdopѩA9w!WT]h,*)-.*.)[:TK,l(-@_SٽR0 7I |6U5c5P +i7Jvtxp8< [:XXߞݞt-- 8\C|xs JCyt߱222653;zve=6;35&.?^{27dn6tclm|dmlxu$<g96g.5.'@1*^ۨ"U\Q:1crfߡl4BϼHgs=N2()*.. Ҡ"z+w!%s6u*u(E.Z8hN[X.Ui bF }ޞ((.osm~1veiݑ0/@$웋 .@SXlgnf#4>jﯕġ ;MHtcg*l |p& -z[MsBhAƬ3dFqj !Mа]zA nc;pYۘٞ[YX]ZBJGk(76 mn< eq\N S2*ÍvE}}ЋOC֡6O, 0e7(.NjH˨+v5谸 rԒlT…T/"?O'/C f8X+kj5AW4SuZ5 v)thp۝fswzk``o`@/"[3;3+[ٙ;Q]ϫ~| Pt1739 GGP"۬f8! nY+Ո2v]}^D0ʨv%˩5DVutEGG֦&7m̓q +U| gigeahy~sqf}azc~rmfli2< DG'wgןNNw5|ѧ4SmZUHDF6L*@c2Iuy!lm죥[.xuU]__^ vM\'?sǿoNo 2>:YtO Y~N2`X* Z DixJvV! (e"JQ'4fjJ&é4E^cOD##`-/MLL^<5:=>=:3232=:=4585 05119ʹ(;Uw6TmiHC c]maMB]-wRKX@/`&bڑ;;KZ)Ji\4ӢUN*FݠgXJ;фVgm @UZZE6<&EIi:`X^[mymnmIOVG;6}|j饀7?>ýFs;?lo\~tMMݛ?8'~*yl,ESaICmA- p|`jN%&%rT O.>\LTr1"ԠK3|j 287plath~lhR h~,6;cC#}9~K3vtwئ{/m~WLFNL3j=ƄnKLR3TZg#SwKko_F*\f^`Jjn4B=}޷ Ԍ+rOUd9^s6<,> `&tM G'z|*z#x)6{&=$ܩ|M,`l[p]a:BYȄkI tJA7VdǬn6)]FEA1ɡKafGd\+*zea/]XwDg GJ<_V:oH7Eo7b4Ow}|~wFbo틴HjtiC6Y^%$k9ZD. ٸ<&6 v}8INzߦ灝5@@`e*7韊OF&}މXxg<3l}{FkAׯZק_n˹Cj]x/b(TYb:B'szdRee2!鵞~_r} J3ܤzgz#aYZ~g%YʲD*W8PpSz 6uӃ ##S+So08ܻ`gģC}F<[‰rH&FW̬թ3Rmqܦ06 e 2Nԋ[̊M눗CZlhk6@-5芴yֿ|;>ǫ9( Cy:'/؎ , ΁}k]]S5 \ZUE6ˈFhǢu&VF9|:*̠4e9\RV%g5MZS-rK!e66P},15591916 z}=OO٦W[Q"vyf)}_/MLz] -KiR&O(y(\z=2FA̒3'rOfY0+TڠK+vuGoyߗRI&ƛ7Ty?-?7-}?d{ӟO GaBpg@5]VeY5 u"IͪR"66ʦ 2 Ć4 2/+:Q'Z_Q(NLPKuc]X?wyÝvgg-4z--ʖVI7ç,f4fLVoczg߬.[YOX)u {,f!O`LR5Nii'%~}"qrFqKv0:K'<=:2 sRS?M0hI9'*sO䝩/< f-:l4;?09lc}jn{~ywqhcn~vbCP.gϧHŸJO"c^&;AfmN6g,f[ [?Pt`M Nl׈M'hPKZ@VyUHfϩM}}?K#y7o?.<ϯ8NvϾ_~?c~{s" FJkX[tN7:Q#)HKzVJpѹLrCMS(,G*-2 [ҀM ,,$j.۽-p' րiQc0ڸ:3Mo;l֍v5iUPY/Pu:bi|'_ y$2$_㕺WUYOϾpސݫ{Ti F"D@[+Y5*F\!,.SWBF30?^7}P>Q{V@o)-Qչ#'`R:20~`wH$0yelNveZ~OJO&DDS\mҚ+yRN$CzN֑ۙng~nIC_ڹ7 7q >w^={qwӟ+d%2h~ߣnv-VVϐ)pBQ[#`W f^W(bB1OGdRi$lu*h` J% BMUFs(-gmP3X1tBnYⒹlSj4_HjY;.- ("7+)b:eT .,o tkJo n*O >(Vs]s>tjѤ|}v֡ov(!,Etxr%ȩz(;Ӝc`6]+:s7#'Kckgl./_Xyhy͇++k33}]aMˡ_H|J3HЦgXDf) ^$ok :Lmei9vgaY9v>]@NwJw{PHYdt\+S">ɟџ~;}/)9_p41<ǑG 82nY=Q\Z/.Wn3v(=Or?Gן'O|;#q9Gneaq#]Kw#ZZCm 'II;v$+㼌JsOKt>sKoXX^{ ŭٹűHw8D]Af V2d [B/SalfȐtbFDՊhZ1uh"FLԐﲩ |ɯ's*q@HRK%"ax&{t?EjC$gōboً{ƜIهL8p=cJڇS]O?j5/I qRH;iYɚY" leZ(Ћ[ P~$zg:9n<\7.-lmLCOY!ʉ%T} ERDVJk9[')DTbwDcqX*.C29&v.VXJ _?jUg~{SؓO`a–?md\m\^&ﷆZu20S$F_ReuTQ%)%3P;|d䡌\ T%lL>!X 3<**+ZS& "!X@*S% 9JɮFmPZ)N0Kb25GőѤFʜC4B" +q;[۵TQYZbyؿZ7C75J_1ط:Xaۙn}tb־;w'ݔSee|Rs,ĽOEA)|]m ړՍ'koလcewai{nasff}brett6LK]8hRxyzDm M/Sh|")GB2Ѥ3 d$5ZW]QxjA" 4wl ! ,x$n~cxcH~_#?-,$.􏮦ᥔ=S^Ls)meHHUdvRC#㜌Osއ `!8O<\Z9c>0ŭٵhto<vVzV1(WZ:(D-~ Q#-4R5^)Wqs*XerfjPe?}j˥u7%I+~99l8l0,!lCAQw3,R ldIx$.1"'*!ʁs05\qH $[$m0rʥ7eSӈu?0U >( i4D:) (abr|>P@-AҊ j!GhbRVzSwEJ!RKQ#W j/V]ȭT۔fqpq7$'ozQy zۿ_Oyrl=FW>nq1 \wk|v3}7?|ħJ$5HJԔ# I/}cޙߝ[z0piG8Zå P؜Y[f&{GPKpN8zX$8臈.F}FBaHr4/B kxٕ nf ^ThoČȱx-}_?hË"~nX뇰潰!wgS-6U`ڍ2tj"O@5ҳj)zvv#'',˙Z^@( elrCNqIiN1&8F)R/ 82ҐAKV%+p!>R(HPRCtf0,\6\pj1RL#Pydr[8Q}覛{r$ fQ f~QY$G:t'JMoyS C1i?|߳aqi{2K.2>JGW֑}I$Or81pBwV 8s@pנpY|,@+kրs٘Z[Fã6o2,2g69 22Dg}N_~Z T9S(!sKF~AFU%ʩ7 o^~3Wa56UUz[TmNy ǟm?~(t/ ߊtaVrXEpRJ)^N%%LE-W T"e Z1* Zӭ5K8H5^BKyBPN!@dqKN‚d>qKm"  7RiT% &fsYM-\9KF뚮emj]tZjaK슳e_d(>]TyMƇuI 7o7j#+auIIz/?ɿ]8N(9(wߎ+P\'11Z? GVo-d" g.F{:c~eZU0*&#f[z9r^/puMe_>'~|kZ)! m sꤹ +ScգcT$#m[M i%|̭Bb\5P5 (PctjYMN5-gX F.hEM ZX%q\Ljʥgjpe8lfZHK"p`t FES1dlI%dSydB.'dpYh\f#:TU!8V1zv̊Y g3!2NH+8St5@ j;op7Io *ސy?Tb!o}l}7~׏#.Js-}W@d|t9# ^L{)y/'p\OwS\w޾뉇-5533}p~nqE5b,:;>ݖ6U'+Xf "`7{8տ9W'~'r/S?~=יwi,,I[3VuR'lȲZ45V6X#a`۴4T*EI2 :)Z!p)9T+Ǖ㫘~^ZNSyXk1j ޠ!4dR3= fjlKX΁+b@ J]*[ySq 5EHuIP]))dD* T* JŢS4 &NGSe]˩Vz&xR񉔢'Ҋ~,5 ""e꿨޿of;?=C7=^zG7_o-$m߅\z Ǖ|tCwS]K-caKCC@듳3O";}qjfub|ydtTpp[v&[ͳH!N/(kܭI?'?~td]IO!#rVMt}5hko~$fEZ@ -A&DgcL2QKZ Z)lk9r]MJ.#ė*hɵ&a!Q^P4 zYG.-fbd4Y/V |l1]#Ak@8@T|M"PQɍ42FBR0dTcRSc1!G$6*S[ynٔ r?ݜO>K;%|sTF DWRǿ9P/셽Ηyo#:Nj`UpS}vƇ733{ͬg~6\@E{1qŤ=y>I;x/Ѝ7>K.XP[Z 10V"ӳi["ޱhw4>ԥd[%d\ :?0ioX7؊716#4))mm:NF4)Ai+z[hzf_cdPe5,Y#Oh  N(X 4&'b!j8J̫eTS*(IU^6VZHU0B-R f50:Gir[T,f &.@pE \Hs)iH/Cq'+n7e=Gf#Plqhdahd>:~j8c >Pƺڇ|>wO͢a%_8xaT7g~?>~/ Pv7ĹU1Z]VM)"ɪZ#G 58DHr J%F 5&@"T Z-lddTSS*i)I1M^V։4H7,ft8-~ Q9*$9VJ~F1 KpdRՉқM7% bpDRC)L#yd)&x|c8xݝ[7ʊ?+OE^ޡ 28x3c7N?p'݌C2.Ln6*{yO6V߃=={q 4ҭ_>;NG9ne\ v1=6.$㇗>?nY{^񼚸jLlzppoz&2( Bo ŀ, ݝChi6vشAU#p*1$&d, M# _鷇!C{07y)ol7IKȻw֝Epi^LvI#r) +Vc2P 7ʅ5@D MJ)R&EJH/gJkR7VLdcdy9SYׂLAD0n5pZvQ,"ۤ`8R>|PH!O'զ@!o6^m(X|QrU~_O'RHTbS ) 2>[{U~V{\)t]م}5)ʆ~v`b7S>?Gr XHXxC}{v,w~/%cO\G3݂oeэg컚 X! V@3G➫IJYnZ|lw"3=5 O{&z{&{{ڇ:Ӯ e>أUjSNEƜBWl{aؗ3;wO>r[ Q݁=?? XN׈sȊN_\JG b!x Oē""8LܤarZR(2FĈTH$)GZvF#/'*9:IhL崰fNӢ,*X AF@-` AB|QLD6.Tv5d\\/(, $|C"~Qq;]amam^:+x/ӳ8vN;<#<U/D-O``Ga[` ?m~b{NxP@p컖j {.&|p! {v/쿒q'eK2dfffffPTvQw5UWwAwQn89w&L|Ow܈'X%WD\$l@1frR>y`{xo~7_߽O^1w/%탅bdiF._Zg; Xh<6ߚ3}D5 N6} ӈ%LSFi$CagJ`TkM /ْ)Z \/Xloeɷ/-{Z]EJ::7g,QήZ6nl{'y8Jo$K]QsrP╤ ԎCrPHP5RQ4eOēFYjPƦ:bdʣvػ?t\ty'gUNf BdVsM ސ٤e3աXɭsg=Trj"zCf`X@uX)z.(VYgЮ8(W)J=фuDQ?AЃubح|`8m"3Ww?y[GOn?d㍻knn6r{+rxYs-gl)z"#wspgcfjᷜ߷q8-5zIhAwس;aC& d2X(q{P`q)oVs%gh2`[XeҲ,ҥ l@~ÛYzwA2\s"l] mvwJtw)Ȼŵa_.A)H: ;?nEOcūx eфA4NhESzɴ^:mOS^HvؓOucCcop/yANg5Y$Hfp!R+&HodpZ^6LDK(dPkh*&I$j4E\FЮW1ZYb 5U 8 '@jրawxnӉde;Cpa^۽wtpxZNm6g[f-)]6H t//DKi|𠘺^lkl㩪o` fط A^ӰWKUdIS~d|GJ̩sn>_rsnѶPr-.yWKޥzhy-^ BC_Tx$y7/UC~ݱ\ߍnƷwݵƒo['gY:}wN~΅4q1i8@H&1\/ ' pB-׈&T1h@;l;{1>KdL|nF[ x]v h`6SX-4vNPLd4J%-^/X% BP$TpE2NH@5|i3z zX^/ӅdwmӴ r-nh]\%hLK}Awnf{<v2vnL KIڬw{>r9^Q~ʯ{-oa}.ד7ijkV?.҇ I+|tҡ7pJJWܢs%BSZ,zWaP V#KۑVdq'n8b`I/)|E(/L16K6zpsſK|B=S"LP ~͍9y;7bcD6 YZKI01 BDi`L-SGQp%kwoXuxvDJcR--, :iqb3 .K&  u*K%$ 0a^AQh5hZ Iހ7"NׇHv9h5LjÝZfe)QZ g-6GStGy}4~?[4ȗ2RRib"G i#r±vm̅KO }D|=Qn-5~= `'sPJi 2ЉSa^!jBtS\NIcy}DIٵPrKsaUZq/yWk;^by7ZލwÅm#b /ieUTe]f͘t|;ͭZpmٷ iVr5 U.ȆAy'Nyq7NƍXq+' hp`bA8Ljj7 ʸC2O:5\}{\{ r+?Z:t^_}vA˅2jZiD; lJ0!+2N6cJԩJ8п\S.#OX`XZ-ZԠB$bwa9hNgvM2ǨͣQR=l}=SXr&_Tp¾1jc7RtEԹs.~t*Jr#"Rq `ݼO (AM!j,'mkY|BE1R -k}g=􍼻w2:{rE6I *N%|2Q0gK’{qSXr/9 UF`c'"( H klv:X;/hGW Iv>|cij܇yדr_)=t gpvB0ۗg@XWiU(!8J~b vXُ.K{-Gj[VLl̪&f*lXb)+bZ5ΥI|B3WL!9`X7FZ@:)١aLJΘ3" C 'l67;QmS3Ǘ`Wa۵;ERn; Nb1Y- f+;ml:4 "։^`.`HL%}0p%2zG#0PSk0?qjZ qg0qF(mrT FgDh2Z<-)ΆUYV!tS~rxڍjz9RC0x*'82.ub AF -%,ko~^Xv.KޕA|0vX=,|sԆ!S̖)aLfW id_4,. 8 9S!c(6C8Ȩ=faԀד}:GJzqwTm F¶`{;ug^|Puu tz;;":x춟`2۸q0IBVaqWpj, pT!(% 2R֓$F)h tN NS'㔦qj8m>Lm$7H &X`te?kAQ4d(F7n]?S7| 0a ?O0Ů(^nTdYr3\fKS"̈́H9.c*%im:\I^xrk6V˱y)Rr3RƛBEҚu+*-s%\ٲ,WvAd \>w=s;>I2[9nH-3+)[J%h*,ZEKq0o*d.mD9+AY/Nyܰ23IudV]*Sᤚ;`R栄9 aKX}JVRl l-6j`fNp.㲁*w =A.> `Y--<Ůln1y~2a0 \Ph"Vc+DU"H%:,lpNJhHus˖šciǿ~^; 6ι]kfېԥ6-}fۘWeU EUfQ+˦() yC>-ds)M. I2!Y:(֬WpCO:ozudP@ှGLŌW0z.O ;a6X 6^-`kMeI. z%G,>jf3Oh䰆&E*MDfKj Ģc >*QJ4"p@L ^!W  , <4sg;ڐխ06Ď;:;gHbpqe:76AlapLΜxn?~'v'WۖYlm* qZYٌ͟JJp+w`p坣'G;+G2d>bYdsL)v0K.*%]n8 ΊYA 4H*nLbREdKZy2_懖eI,%EL"SP9|9BHogRqJ<<qpTUxT%yD"*D4j U90Vb1U =3:tL霮h9ߊjETÔ6A1b@L>ʐS5 bk[ٍ+œ+w.):JU 7o:m`]] s9[4'v~7ܹy\,s@T]>=2P/ ٲ*Qz3GDѢ0( eqdEPķMqd]Mg]W5ahUYGW:]|3Uh^3 `!٤|6&˄[QFЗP@+@L"?#5,c }| d>CH<%SL1zNY`kLF.p*&)|.HLa`P+Ss{UN9]j1[f>Gqn5ryMBhFjKd<YAD] J<<QG!f*33 ㈊1q1QaA>DE7l 9xLc"aU8tѨM ɑv''EoofŲкε 'R?A@qS0A5@P4,ݘ̈Q0"DRѨjk-d݃[>{!dmm } (eߝ$8̐#YFl,p3%IxM37ϳy K|pX7D Q`uwZE5Qx]^EeyjI^ҜU@$SsTFJQq<(zyAgh7%.ǚ% Ǹ5`I"j/!KHz@^WS5!o^lQbҡ^ʣ5C:e;6~>-[R;%vU@k{%"ļ>L%F\S8* H .?Wf!'LFW+F#Ȋad}Yх8ׅDo਄IzE~4\,!DjJKg'A( E.ƒx l U;!Eӂ~ˌ.lC N3FEh,䅼~ŝA_rkAh+(AȠe# _bq? ϒ#shX` lwY7"+Pb{YEt/f7؝RF* j57CNHFU .?9>< 8;3qfjԹs3f΍ΜAU b.+] 6T5L,&$"J5(3cgle5*LM0W:'9|n"ȇŽINaQ4Ĭe׎q&yVOG総ؾ{t5X.Y% R@ c|QLGHyF|ܳ4wꝧE`Q"Yf8 *˽nr{bߖ- B4'o }N8P,NI,`H ^ ^f4]j]C-Y Y4cN޸Ҙ?& ḉ?n1x.rɀg jLX q%+Gd.>#\!1Ӊ#P6 :z)pN& ]MF] #/@'S͜LEOE?3=;31~f|䙱FgQC #Ale?( ERQr>R%FdSSOjHF5dF 7pHe+TOMbd31V~^3H^]b\b^a׍sI/C9fsk;J'%)oΦkX揓+D6LJ3<+U<70\Xpӝyhb/me}ZcxWܕ@}Yh_n<'`h,3]E+tY;ę;=tⶑfKPr Sqq.9 㒣rSr0?oQ pk h&wIp#a\u?] DUZU2):I/#d$#88uJfUT,hz8A9%S1N(y0Ȩb \ G8 A딨 !#T6J*Ws|mk~-^v/fS`nВ+$$֝y@D X/rB`^C |__{ ݘ!fIYil)RmK ˾qm<#yX:V]od:֨%unS9=Cs&8yTPi3ө|" 9 )&c@ۨ~3U8?M8acðQ(lx 64yf~v] $a {[ٍ9BoSsJEI(hVͦZn ,IˤfdhF7-ws;9mv0 2n4j<dtΈ$Ȅ&G;rph-dɄ%kxf䛶D$ڞ*2XYlozL\m Hp`=tq;'8ܶ1N(i8NNiHT\NGO13 ch6s̜>*:?6 -Ci߃yM"Uq"Nuئؕq6%=StU:DŽƈƙm#F( E`b8}6is&x-Pۧ ) ǥj"c>-=Zp9{^/; tRl9Q9̢MY5 gZd{E9Y>Eʼn(^cj06A$A5K/P+l-;b?c_~7yu+EvȋyQ:'d/dclD !I9([*ւ͈~/nO擴Zr-GI㵔fzsv3c=N(V<nșiI=$KTM4h~9+e,q> zsYVj +w054%KTT*\@O8@8 3c834yfh,H(\ 8*PQeWES4X,ڕ).큀Hy 9y>l ^%d${4Hof0[!8gpyE'x| ~uR:!luLL}HA=p3E͇w,ؙ;JlKtJΡ#(C n H,ʐZ*rَ4I cXE T!>J4DEH`9yX7 oDvđ-ahC\yK) (SsbVOKrJRn&U[qnB7mi͜Vugsw`so}}{\ߟ߿9k6' 1^D{E^ c?:) @'wI-QVQF l4)24N'^!/qHeHj /K$T5~;]<<887=ynbi``О1B څ:L18HcvUҥI{i c>l)DmX@c*J88h6 9Ơ4wMS9!wN u۔cF F7\ ̈́Z[< ɍ5>$nFk3&=N#5chY\xxU64I2В\@*hM`,I)FӆHAi2CjYJ ˻ kȚ0 2?V&d%E.TEmyAWis9ntfײ99ݼQ1d1l1y^ =+/G_ğ/Ş"G%;9YIJSm"U/D̬7ځɑn)!7UHğS*HZxBB&@XP i e*]&c.Qqj 3]>DT\9785F [?$s~%eYVyĦL8T)>3Cm.jD.H%ҤS!j 0i:J$skR1-lƴ!QavRcnf}t}E},.ժJB'%qibRQdynhYb8Xc{6UeI,% `59J%YpY>G2͓T{O ,qK2/Z%$tnI)-LK%΢a`+ZkEϭ「ba) \I^IYI^NYMH]O^MZ<+,ϻlA助C p *=k 8A%گ@3V7t8Z~4HZiZ* xJB'1-@ Wh`!SJHj4 >ΎSElE7[lS ֒ X*Zn\T9ql*4:*K231Ho76|G7cZ5#<PB;PtepyF5B1ݹ{w]yp~kxZ_-Mلmʵ(FGqQbZB*Xmh(+Lצ-ro m\c)<R?B(XclK2@hD91KyX(G"(Yee%ʪ~uմjY/,GKkeϭ%۵7s76r>lϽߚ{{~x<0ݷ@ʤ QvP윅2cZTNT! o@R,zQ$Lce+3zFJ#0(LJ-Zˡqi^vX[ ?܈?H?ʼڞ{=v~{Vۅ;mG;ŏ?+~Y`$//DḋPKUeoJ10^\H% |` V=l5IC@<mN@)КZ:E0L&>z£5) ,R=XOR5T|-WC]b QUS \MÀz0b\5ͬ%][C>l1IX"ox6LmlqR=Ik): s_>7ug;p` Ϗ*ǨaNqkn]9Gҫ;D=-w SA6њv e2ƅj 4oGPV!nMIsHQAa&CDxcbђ*QV#;!讀zI~u矆~mdv} poɬK\C%)3xe a!1D `ci-Kg)3aӜPrdqA\2l.W'5ύuнӭݹwŏN?ϯo毯mx|~ Õ_B,}S{~*Zj ,vzdYgM,^.4ǵ%K&E4|AcIf;j[Dv SR :Bq:El>Kid!ׁpWIąSI<g0 qr5,%[3>M%XyR4S)azG,)m#QN+رS1oEZf%lNI:@=x( xI"nnom'WC8&0Z1XZ0 z߮ruvu0i wFE6x:E`_SvT-cMd) d]N1)J2QƪCoMYw˲|V X4;=+ω ҍEhqm ȸ~sp͵_՝ݝ/~q{[nom֯omd_.WۍYWk2OJ{y ^I@5SbD~%?du˘"FBp99aa0iYbe.S =ڭv+=JA;Sj24C)CN!.0cۘ Ώ.`:lQCp*6䊧f>Rء;̖QVik:$kFo4O>DHYI?ɶc^"ǁˋk[zxeUr(Qс8׎Uw/.QCqnRv"-ea`_:4t cMl-qfR)0UeXdchOS< *y&PIc)V2ŝϊyfIsl꼹꽻z~sXl|p'_=pw}p}q{777}}Wk_x7ZQmf߮|^?,xoZڍxɁZ|P)PNɴU8!f ]*)aS@:X8vy"aD%*jYFګ=[."怿U@oP8\%b0WȪ3Sgf "OT X$hDM3s*;\68@8q, f'mi~4i7  p,rjf;|7fRIZro--͑ KoEB u ϵ*zս]KԚAzn^7la,;F'-eE`)qL ,5OHaygyQ u(՛cGDI*Eq H,/a2b [2no^f>[>G7}x׾xO{_,vXtԑw mͽY}}໙&a٢;kuDP8*c,r{ /MQJf{=Ea2$)W,Jzb@6F A_'JzU~W!Z`|z@A#j+dig>ݰsC؊|,`x |4 fSOW1$XO1pZHA=uhrGOoM&-ina8o e=2Ŷ#6$I3FyBgsɻRv:b[ =TщU/v⪺I5>>z ~J j'f40M$Uh˜bМ$<'ӟf3`[VՅ%UłT,ȶUMϽӃ7V~qkwv~{ˇ'_=ӛ~zv'w֟?=k{5h鳃O! )ߙ{9crW%n0CWvA0`uG[*)jx&]g7ZL^b@kFL1vܢ5iG!JC:F6}Ja#t9BV  W D csvw ЛmQ7rmZX2{IīzcNzzc¢m  jN8m6NMӂjg)a/%ǴNœqh[, P>21A]T8:U YHzWz)W{i5"4#e͒u!Ͱ$ϟD9A8ˏɼ0]̯(+uqsUb]1Yol턟^e_̿9ο;)|t}KZo}׏֟_գz?>?г?;=r㫇_?{ ^-G<z/^pfJDO 1"U h&6s-0epUh-&Ikhr9\"T*vĬ' '1zĨ+u!tH%S{0br 4UBE@phØs Kwyno|&̮bM/ 8| رPKAˆ(891N(a \pƹ 'In F Q#;YlSՇ9u>2I)5!F0v]tTC$݄~v@!BTsJa 9A|^)eªaX۶mw]G;mΖNa͵»ŏn-}rkkkӳ;߽|㛧{o_x?^?˫'}򗗧ļxd*>/n/WWji!6kۋV|‚0:_uQvɤQ0fca4(2h EK#*A?n2SN˔6N,NifmQԣF^:F"wYMLZtVN*FgZF'T*]vjy>ct4xzOmt( c2 l. pBԏrhQn8(Tu#xF> "%h^>E &5Hctiwpi\3HfԂy2#lv$ Q?yHNGr cQ2,/Jmhu9lnlnE_*}zg~y;yۿ}㣯/~^O|o>Xyoo_^?Ń?>8onndme_-;OҦ|Y`UN#toCDkК8FE(Q&h8jB)u1if>DHw"<׎θ,.S?nՌ#:ـR%液j-xT!8gGq'H0aSZXF#%2zA᠂l cCf-P(q83>~8kU6#uN '=q8gh3<N(qQ3N73Fu# "Iyav(nR؄vbHi'Nѥ5E(DlYVXUի[{}mu}ug7xo?08V{k?_?/}LJ_=͋[߿w?~>}~'Goѫ|xw@瀒~{8y?ڙ|jwGI=4U\ܔ` ]:cNCJVCm`|r@dxCrdbmPS*L5iibv;P>'*Aؠ>|؏ /6A("?ɷ/o>ˇ'??y>ggg~xsooc,z|׾[۹W'ݼy/&_ l̨U4sL6"+fOo*&4;&#ר(zltplԇ !"&"Tr"DJp16DHeҮ7!j$jФKӄ l8b[1A8?I_T0&TX TG}?q){$GaFCzHAVC" P4{!SN4af0{; Zh:^~^ӳ|_AQrzvZCϼ:ƫ҉1(d"Lʰŝ`nI"/kW7;;#ϝc׽kgo^7d_>?㋓_?׷x/#`{w}50Xx~On}u;{`^FrVFzHw&_  1fiRZʔ>CPkFZ-Zw;A/6 BdP1lMfm.F&t])0m4~m&k0b$$4 θ3n;`86TMf{'}~]*vNI3}tg SQj0EgY?zO7|>~{zB/~7ono5~dO҆ݨZ! lW~(oLӻ%NCHm¥Y|NH88L<գ6ύq0i6Fc>ȧsiV>ZHҴ\gÄuiPTAG hc4cT=C]D2/ RSA3a)nb->ros@k)HFfB"fg>ا3@ubOi [CL^Z]'JR;r?SٍUCX; \C4ʮH۸mR`:#|G R(ɈͲ9|_X,.IW[}ӭcއ7|oL~woK?^ӝ??^_Սݝp|ǯ} xoQ>ǻ砓џdiG{ o7Rϗ" `&4k~QN)>%)6 ua[JQEThr(y k dS i|^3avLćOG(8u!,Xv)-eo1)eYYV1hlnV̰V+ws-FzC_A/WЬ+XN L'&ٕt5276Hj&jA'ࠀ5 =#8ay`~  Q;+P|@X >$!> DͽnV|u EWu+?.v:UBu' qqQKV0ulO?׌KtS*+X=x{ #dr\[(eʊb{SugydsɭЋ۱7f?ϟl8x'߼훛z{뻷|{9#8zywc ر}/^=Ž??ՃQN(]'i^D` M@5PĜ1Ī`>>jZ@ݥRMEAԆngX A@=} søjk v\]LySQ ,Znj4/heX^oɗ~{k'+|Vi[NBO*v Z(Q {PS;V>Amd2ٜvpPc"\WPHr:4 \6'\l/ ;E^I$?X%EΕ8uH ia#|v  l#I:.OlZFUI&x#pPexc]:^?2޾fyx]g?{V^| oOy X?6kO㫻?~㫇߿~rG;;sbOJ{9IR\QRE0e8#jd [Dk㒛FFkzHv+_ԯ3l^7K,C|E"d$[V-+V#^Q_D9v9I bnD 2Hukr e0=4Ȩl_?K52 x-g(RhFވa@MDA IJSt5=|}<"7Cøp̹"wqY&Rl(5׎ Oo;^y8ٳǯ_֗ozsǵoӻ߽rhzsXȏ /o_/P72O Λ݈l˟0ZWi8 P~6] z&NJ%>h:nP:hAq0O:p(-w˒%rE}>YpYs(!GYϱI\ùbhU=2IHrElQ3)mf(ZXVRHJ:%C&'}]K*GIr^!rzO}z VGnA' RRy"*Xݒn쨷Uck7o9zx(ϋ|Q˵߿ۃ}w;?~|}O=G?{?y,;P?8} J7KyqJ/:-ƻ$RQ1 &=bV.AJ_!R(54F#,t)#V)R\:6DxW/ wD{˒ڦڦڦں`E QY(vQAT=峌X 9NCChdKX&iIy8(9" btv0/@]7\&]f Z a DJ,m`v:P2N`ъ=ԁddN'['QZ !_ 2@Yb f,$Ŭ&h~eX7QT CH橹2_ْm*{G5M{oE?<|t/ |Yͫ/}OOÿ|û? %ǷOn|~skk,ݞ} نfּWzsZ\G)7fLM|J QWIU*V`7DRU8R"Ie"eʦ,)Fr^9`]~^U$?\아[J Άqό>n54rEL! ŭ|I_ʑ4e-,e+WBrg|CIENDB`gift-0.2.0/transform.go000066400000000000000000000310051513354670200150110ustar00rootroot00000000000000package gift import ( "image" "image/color" "image/draw" ) type transformType int const ( ttRotate90 transformType = iota ttRotate180 ttRotate270 ttFlipHorizontal ttFlipVertical ttTranspose ttTransverse ) type transformFilter struct { tt transformType } func (p *transformFilter) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { if p.tt == ttRotate90 || p.tt == ttRotate270 || p.tt == ttTranspose || p.tt == ttTransverse { dstBounds = image.Rect(0, 0, srcBounds.Dy(), srcBounds.Dx()) } else { dstBounds = image.Rect(0, 0, srcBounds.Dx(), srcBounds.Dy()) } return } func (p *transformFilter) Draw(dst draw.Image, src image.Image, options *Options) { if options == nil { options = &defaultOptions } srcb := src.Bounds() dstb := dst.Bounds() pixGetter := newPixelGetter(src) pixSetter := newPixelSetter(dst) parallelize(options.Workers, srcb.Min.Y, srcb.Max.Y, func(start, stop int) { for srcy := start; srcy < stop; srcy++ { for srcx := srcb.Min.X; srcx < srcb.Max.X; srcx++ { var dstx, dsty int switch p.tt { case ttRotate90: dstx = dstb.Min.X + srcy - srcb.Min.Y dsty = dstb.Min.Y + srcb.Max.X - srcx - 1 case ttRotate180: dstx = dstb.Min.X + srcb.Max.X - srcx - 1 dsty = dstb.Min.Y + srcb.Max.Y - srcy - 1 case ttRotate270: dstx = dstb.Min.X + srcb.Max.Y - srcy - 1 dsty = dstb.Min.Y + srcx - srcb.Min.X case ttFlipHorizontal: dstx = dstb.Min.X + srcb.Max.X - srcx - 1 dsty = dstb.Min.Y + srcy - srcb.Min.Y case ttFlipVertical: dstx = dstb.Min.X + srcx - srcb.Min.X dsty = dstb.Min.Y + srcb.Max.Y - srcy - 1 case ttTranspose: dstx = dstb.Min.X + srcy - srcb.Min.Y dsty = dstb.Min.Y + srcx - srcb.Min.X case ttTransverse: dstx = dstb.Min.Y + srcb.Max.Y - srcy - 1 dsty = dstb.Min.X + srcb.Max.X - srcx - 1 } pixSetter.setPixel(dstx, dsty, pixGetter.getPixel(srcx, srcy)) } } }) } // Rotate90 creates a filter that rotates an image 90 degrees counter-clockwise. func Rotate90() Filter { return &transformFilter{ tt: ttRotate90, } } // Rotate180 creates a filter that rotates an image 180 degrees counter-clockwise. func Rotate180() Filter { return &transformFilter{ tt: ttRotate180, } } // Rotate270 creates a filter that rotates an image 270 degrees counter-clockwise. func Rotate270() Filter { return &transformFilter{ tt: ttRotate270, } } // FlipHorizontal creates a filter that flips an image horizontally. func FlipHorizontal() Filter { return &transformFilter{ tt: ttFlipHorizontal, } } // FlipVertical creates a filter that flips an image vertically. func FlipVertical() Filter { return &transformFilter{ tt: ttFlipVertical, } } // Transpose creates a filter that flips an image horizontally and rotates 90 degrees counter-clockwise. func Transpose() Filter { return &transformFilter{ tt: ttTranspose, } } // Transverse creates a filter that flips an image vertically and rotates 90 degrees counter-clockwise. func Transverse() Filter { return &transformFilter{ tt: ttTransverse, } } // Interpolation is an interpolation algorithm used for image transformation. type Interpolation int const ( // NearestNeighborInterpolation is a nearest-neighbor interpolation algorithm. NearestNeighborInterpolation Interpolation = iota // LinearInterpolation is a bilinear interpolation algorithm. LinearInterpolation // CubicInterpolation is a bicubic interpolation algorithm. CubicInterpolation ) func rotatePoint(x, y, asin, acos float32) (float32, float32) { newx := x*acos - y*asin newy := x*asin + y*acos return newx, newy } func calcRotatedSize(w, h int, angle float32) (int, int) { if w <= 0 || h <= 0 { return 0, 0 } xoff := float32(w)/2 - 0.5 yoff := float32(h)/2 - 0.5 asin, acos := sincosf32(angle) x1, y1 := rotatePoint(0-xoff, 0-yoff, asin, acos) x2, y2 := rotatePoint(float32(w-1)-xoff, 0-yoff, asin, acos) x3, y3 := rotatePoint(float32(w-1)-xoff, float32(h-1)-yoff, asin, acos) x4, y4 := rotatePoint(0-xoff, float32(h-1)-yoff, asin, acos) minx := minf32(x1, minf32(x2, minf32(x3, x4))) maxx := maxf32(x1, maxf32(x2, maxf32(x3, x4))) miny := minf32(y1, minf32(y2, minf32(y3, y4))) maxy := maxf32(y1, maxf32(y2, maxf32(y3, y4))) neww := maxx - minx + 1 if neww-floorf32(neww) > 0.01 { neww += 2 } newh := maxy - miny + 1 if newh-floorf32(newh) > 0.01 { newh += 2 } return int(neww), int(newh) } type rotateFilter struct { angle float32 bgcolor color.Color interpolation Interpolation } func (p *rotateFilter) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { w, h := calcRotatedSize(srcBounds.Dx(), srcBounds.Dy(), p.angle) dstBounds = image.Rect(0, 0, w, h) return } func (p *rotateFilter) Draw(dst draw.Image, src image.Image, options *Options) { if options == nil { options = &defaultOptions } srcb := src.Bounds() dstb := dst.Bounds() w, h := calcRotatedSize(srcb.Dx(), srcb.Dy(), p.angle) if w <= 0 || h <= 0 { return } srcxoff := float32(srcb.Dx())/2 - 0.5 srcyoff := float32(srcb.Dy())/2 - 0.5 dstxoff := float32(w)/2 - 0.5 dstyoff := float32(h)/2 - 0.5 bgpx := pixelFromColor(p.bgcolor) asin, acos := sincosf32(p.angle) pixGetter := newPixelGetter(src) pixSetter := newPixelSetter(dst) parallelize(options.Workers, 0, h, func(start, stop int) { for y := start; y < stop; y++ { for x := range w { xf, yf := rotatePoint(float32(x)-dstxoff, float32(y)-dstyoff, asin, acos) xf, yf = float32(srcb.Min.X)+xf+srcxoff, float32(srcb.Min.Y)+yf+srcyoff var px pixel switch p.interpolation { case CubicInterpolation: px = interpolateCubic(xf, yf, srcb, pixGetter, bgpx) case LinearInterpolation: px = interpolateLinear(xf, yf, srcb, pixGetter, bgpx) default: px = interpolateNearest(xf, yf, srcb, pixGetter, bgpx) } pixSetter.setPixel(dstb.Min.X+x, dstb.Min.Y+y, px) } } }) } func interpolateCubic(xf, yf float32, bounds image.Rectangle, pixGetter *pixelGetter, bgpx pixel) pixel { var pxs [16]pixel var cfs [16]float32 var px pixel x0, y0 := int(floorf32(xf)), int(floorf32(yf)) if !image.Pt(x0, y0).In(image.Rect(bounds.Min.X-1, bounds.Min.Y-1, bounds.Max.X, bounds.Max.Y)) { return bgpx } xq, yq := xf-float32(x0), yf-float32(y0) for i := range 4 { for j := range 4 { pt := image.Pt(x0+j-1, y0+i-1) if pt.In(bounds) { pxs[i*4+j] = pixGetter.getPixel(pt.X, pt.Y) } else { pxs[i*4+j] = bgpx } } } const ( k04 = 1 / 4.0 k12 = 1 / 12.0 k36 = 1 / 36.0 ) cfs[0] = k36 * xq * yq * (xq - 1) * (xq - 2) * (yq - 1) * (yq - 2) cfs[1] = -k12 * yq * (xq - 1) * (xq - 2) * (xq + 1) * (yq - 1) * (yq - 2) cfs[2] = k12 * xq * yq * (xq + 1) * (xq - 2) * (yq - 1) * (yq - 2) cfs[3] = -k36 * xq * yq * (xq - 1) * (xq + 1) * (yq - 1) * (yq - 2) cfs[4] = -k12 * xq * (xq - 1) * (xq - 2) * (yq - 1) * (yq - 2) * (yq + 1) cfs[5] = k04 * (xq - 1) * (xq - 2) * (xq + 1) * (yq - 1) * (yq - 2) * (yq + 1) cfs[6] = -k04 * xq * (xq + 1) * (xq - 2) * (yq - 1) * (yq - 2) * (yq + 1) cfs[7] = k12 * xq * (xq - 1) * (xq + 1) * (yq - 1) * (yq - 2) * (yq + 1) cfs[8] = k12 * xq * yq * (xq - 1) * (xq - 2) * (yq + 1) * (yq - 2) cfs[9] = -k04 * yq * (xq - 1) * (xq - 2) * (xq + 1) * (yq + 1) * (yq - 2) cfs[10] = k04 * xq * yq * (xq + 1) * (xq - 2) * (yq + 1) * (yq - 2) cfs[11] = -k12 * xq * yq * (xq - 1) * (xq + 1) * (yq + 1) * (yq - 2) cfs[12] = -k36 * xq * yq * (xq - 1) * (xq - 2) * (yq - 1) * (yq + 1) cfs[13] = k12 * yq * (xq - 1) * (xq - 2) * (xq + 1) * (yq - 1) * (yq + 1) cfs[14] = -k12 * xq * yq * (xq + 1) * (xq - 2) * (yq - 1) * (yq + 1) cfs[15] = k36 * xq * yq * (xq - 1) * (xq + 1) * (yq - 1) * (yq + 1) for i := range pxs { wa := pxs[i].a * cfs[i] px.r += pxs[i].r * wa px.g += pxs[i].g * wa px.b += pxs[i].b * wa px.a += wa } if px.a != 0 { px.r /= px.a px.g /= px.a px.b /= px.a } return px } func interpolateLinear(xf, yf float32, bounds image.Rectangle, pixGetter *pixelGetter, bgpx pixel) pixel { var pxs [4]pixel var cfs [4]float32 var px pixel x0, y0 := int(floorf32(xf)), int(floorf32(yf)) if !image.Pt(x0, y0).In(image.Rect(bounds.Min.X-1, bounds.Min.Y-1, bounds.Max.X, bounds.Max.Y)) { return bgpx } xq, yq := xf-float32(x0), yf-float32(y0) for i := range 2 { for j := range 2 { pt := image.Pt(x0+j, y0+i) if pt.In(bounds) { pxs[i*2+j] = pixGetter.getPixel(pt.X, pt.Y) } else { pxs[i*2+j] = bgpx } } } cfs[0] = (1 - xq) * (1 - yq) cfs[1] = xq * (1 - yq) cfs[2] = (1 - xq) * yq cfs[3] = xq * yq for i := range pxs { wa := pxs[i].a * cfs[i] px.r += pxs[i].r * wa px.g += pxs[i].g * wa px.b += pxs[i].b * wa px.a += wa } if px.a != 0 { px.r /= px.a px.g /= px.a px.b /= px.a } return px } func interpolateNearest(xf, yf float32, bounds image.Rectangle, pixGetter *pixelGetter, bgpx pixel) pixel { x0, y0 := int(floorf32(xf+0.5)), int(floorf32(yf+0.5)) if image.Pt(x0, y0).In(bounds) { return pixGetter.getPixel(x0, y0) } return bgpx } // Rotate creates a filter that rotates an image by the given angle counter-clockwise. // The angle parameter is the rotation angle in degrees. // The backgroundColor parameter specifies the color of the uncovered zone after the rotation. // The interpolation parameter specifies the interpolation method. // Supported interpolation methods: NearestNeighborInterpolation, LinearInterpolation, CubicInterpolation. // // Example: // // g := gift.New( // gift.Rotate(45, color.Black, gift.LinearInterpolation), // ) // dst := image.NewRGBA(g.Bounds(src.Bounds())) // g.Draw(dst, src) func Rotate(angle float32, backgroundColor color.Color, interpolation Interpolation) Filter { return &rotateFilter{ angle: angle, bgcolor: backgroundColor, interpolation: interpolation, } } type cropFilter struct { rect image.Rectangle } func (p *cropFilter) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { b := srcBounds.Intersect(p.rect) return b.Sub(b.Min) } func (p *cropFilter) Draw(dst draw.Image, src image.Image, options *Options) { if options == nil { options = &defaultOptions } srcb := src.Bounds().Intersect(p.rect) dstb := dst.Bounds() pixGetter := newPixelGetter(src) pixSetter := newPixelSetter(dst) parallelize(options.Workers, srcb.Min.Y, srcb.Max.Y, func(start, stop int) { for srcy := start; srcy < stop; srcy++ { for srcx := srcb.Min.X; srcx < srcb.Max.X; srcx++ { dstx := dstb.Min.X + srcx - srcb.Min.X dsty := dstb.Min.Y + srcy - srcb.Min.Y pixSetter.setPixel(dstx, dsty, pixGetter.getPixel(srcx, srcy)) } } }) } // Crop creates a filter that crops the specified rectangular region from an image. // // Example: // // g := gift.New( // gift.Crop(image.Rect(100, 100, 200, 200)), // ) // dst := image.NewRGBA(g.Bounds(src.Bounds())) // g.Draw(dst, src) func Crop(rect image.Rectangle) Filter { return &cropFilter{ rect: rect, } } // Anchor is the anchor point for image cropping. type Anchor int // Anchor point positions. const ( CenterAnchor Anchor = iota TopLeftAnchor TopAnchor TopRightAnchor LeftAnchor RightAnchor BottomLeftAnchor BottomAnchor BottomRightAnchor ) func anchorPt(b image.Rectangle, w, h int, anchor Anchor) image.Point { var x, y int switch anchor { case TopLeftAnchor: x = b.Min.X y = b.Min.Y case TopAnchor: x = b.Min.X + (b.Dx()-w)/2 y = b.Min.Y case TopRightAnchor: x = b.Max.X - w y = b.Min.Y case LeftAnchor: x = b.Min.X y = b.Min.Y + (b.Dy()-h)/2 case RightAnchor: x = b.Max.X - w y = b.Min.Y + (b.Dy()-h)/2 case BottomLeftAnchor: x = b.Min.X y = b.Max.Y - h case BottomAnchor: x = b.Min.X + (b.Dx()-w)/2 y = b.Max.Y - h case BottomRightAnchor: x = b.Max.X - w y = b.Max.Y - h default: x = b.Min.X + (b.Dx()-w)/2 y = b.Min.Y + (b.Dy()-h)/2 } return image.Pt(x, y) } type cropToSizeFilter struct { w, h int anchor Anchor } func (p *cropToSizeFilter) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { if p.w <= 0 || p.h <= 0 { return image.Rect(0, 0, 0, 0) } pt := anchorPt(srcBounds, p.w, p.h, p.anchor) r := image.Rect(0, 0, p.w, p.h).Add(pt) b := srcBounds.Intersect(r) return b.Sub(b.Min) } func (p *cropToSizeFilter) Draw(dst draw.Image, src image.Image, options *Options) { if p.w <= 0 || p.h <= 0 { return } pt := anchorPt(src.Bounds(), p.w, p.h, p.anchor) r := image.Rect(0, 0, p.w, p.h).Add(pt) b := src.Bounds().Intersect(r) Crop(b).Draw(dst, src, options) } // CropToSize creates a filter that crops an image to the specified size using the specified anchor point. func CropToSize(width, height int, anchor Anchor) Filter { return &cropToSizeFilter{ w: width, h: height, anchor: anchor, } } gift-0.2.0/transform_test.go000066400000000000000000000344151513354670200160600ustar00rootroot00000000000000package gift import ( "bytes" "image" "image/color" "testing" ) func TestRotate90(t *testing.T) { img0 := image.NewGray(image.Rect(-1, -1, 3, 1)) img0.Pix = []uint8{ 1, 2, 3, 4, 5, 6, 7, 8, } img1Exp := image.NewGray(image.Rect(0, 0, 2, 4)) img1Exp.Pix = []uint8{ 4, 8, 3, 7, 2, 6, 1, 5, } f := Rotate90() img1 := image.NewGray(f.Bounds(img0.Bounds())) f.Draw(img1, img0, nil) if img1.Bounds().Size() != img1Exp.Bounds().Size() { t.Errorf("expected %v got %v", img1Exp.Bounds().Size(), img1.Bounds().Size()) } if !bytes.Equal(img1Exp.Pix, img1.Pix) { t.Errorf("expected %v got %v", img1Exp.Pix, img1.Pix) } } func TestRotate180(t *testing.T) { img0 := image.NewGray(image.Rect(-1, -1, 3, 1)) img0.Pix = []uint8{ 1, 2, 3, 4, 5, 6, 7, 8, } img1Exp := image.NewGray(image.Rect(0, 0, 4, 2)) img1Exp.Pix = []uint8{ 8, 7, 6, 5, 4, 3, 2, 1, } f := Rotate180() img1 := image.NewGray(f.Bounds(img0.Bounds())) f.Draw(img1, img0, nil) if img1.Bounds().Size() != img1Exp.Bounds().Size() { t.Errorf("expected %v got %v", img1Exp.Bounds().Size(), img1.Bounds().Size()) } if !bytes.Equal(img1Exp.Pix, img1.Pix) { t.Errorf("expected %v got %v", img1Exp.Pix, img1.Pix) } } func TestRotate270(t *testing.T) { img0 := image.NewGray(image.Rect(-1, -1, 3, 1)) img0.Pix = []uint8{ 1, 2, 3, 4, 5, 6, 7, 8, } img1Exp := image.NewGray(image.Rect(0, 0, 2, 4)) img1Exp.Pix = []uint8{ 5, 1, 6, 2, 7, 3, 8, 4, } f := Rotate270() img1 := image.NewGray(f.Bounds(img0.Bounds())) f.Draw(img1, img0, nil) if img1.Bounds().Size() != img1Exp.Bounds().Size() { t.Errorf("expected %v got %v", img1Exp.Bounds().Size(), img1.Bounds().Size()) } if !bytes.Equal(img1Exp.Pix, img1.Pix) { t.Errorf("expected %v got %v", img1Exp.Pix, img1.Pix) } } func TestFlipHorizontal(t *testing.T) { img0 := image.NewGray(image.Rect(-1, -1, 3, 1)) img0.Pix = []uint8{ 1, 2, 3, 4, 5, 6, 7, 8, } img1Exp := image.NewGray(image.Rect(0, 0, 4, 2)) img1Exp.Pix = []uint8{ 4, 3, 2, 1, 8, 7, 6, 5, } f := FlipHorizontal() img1 := image.NewGray(f.Bounds(img0.Bounds())) f.Draw(img1, img0, nil) if img1.Bounds().Size() != img1Exp.Bounds().Size() { t.Errorf("expected %v got %v", img1Exp.Bounds().Size(), img1.Bounds().Size()) } if !bytes.Equal(img1Exp.Pix, img1.Pix) { t.Errorf("expected %v got %v", img1Exp.Pix, img1.Pix) } } func TestFlipVertical(t *testing.T) { img0 := image.NewGray(image.Rect(-1, -1, 3, 1)) img0.Pix = []uint8{ 1, 2, 3, 4, 5, 6, 7, 8, } img1Exp := image.NewGray(image.Rect(0, 0, 4, 2)) img1Exp.Pix = []uint8{ 5, 6, 7, 8, 1, 2, 3, 4, } f := FlipVertical() img1 := image.NewGray(f.Bounds(img0.Bounds())) f.Draw(img1, img0, nil) if img1.Bounds().Size() != img1Exp.Bounds().Size() { t.Errorf("expected %v got %v", img1Exp.Bounds().Size(), img1.Bounds().Size()) } if !bytes.Equal(img1Exp.Pix, img1.Pix) { t.Errorf("expected %v got %v", img1Exp.Pix, img1.Pix) } } func TestTranspose(t *testing.T) { img0 := image.NewGray(image.Rect(-1, -1, 3, 1)) img0.Pix = []uint8{ 1, 2, 3, 4, 5, 6, 7, 8, } img1Exp := image.NewGray(image.Rect(0, 0, 2, 4)) img1Exp.Pix = []uint8{ 1, 5, 2, 6, 3, 7, 4, 8, } f := Transpose() img1 := image.NewGray(f.Bounds(img0.Bounds())) f.Draw(img1, img0, nil) if img1.Bounds().Size() != img1Exp.Bounds().Size() { t.Errorf("expected %v got %v", img1Exp.Bounds().Size(), img1.Bounds().Size()) } if !bytes.Equal(img1Exp.Pix, img1.Pix) { t.Errorf("expected %v got %v", img1Exp.Pix, img1.Pix) } } func TestTransverse(t *testing.T) { img0 := image.NewGray(image.Rect(-1, -1, 3, 1)) img0.Pix = []uint8{ 1, 2, 3, 4, 5, 6, 7, 8, } img1Exp := image.NewGray(image.Rect(0, 0, 2, 4)) img1Exp.Pix = []uint8{ 8, 4, 7, 3, 6, 2, 5, 1, } f := Transverse() img1 := image.NewGray(f.Bounds(img0.Bounds())) f.Draw(img1, img0, nil) if img1.Bounds().Size() != img1Exp.Bounds().Size() { t.Errorf("expected %v got %v", img1Exp.Bounds().Size(), img1.Bounds().Size()) } if !bytes.Equal(img1Exp.Pix, img1.Pix) { t.Errorf("expected %v got %v", img1Exp.Pix, img1.Pix) } } func TestCrop(t *testing.T) { testData := []struct { desc string r image.Rectangle srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "crop (0, 0, 0, 0)", image.Rect(0, 0, 0, 0), image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 0, 0), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{}, }, { "crop (1, 1, -1, -1)", image.Rectangle{image.Pt(1, 1), image.Pt(-1, -1)}, image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 0, 0), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{}, }, { "crop (-1, 0, 3, 2)", image.Rect(-1, 0, 3, 2), image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 4, 2), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x60, 0xB0, 0xA0, 0xB0, 0x00, 0x80, 0x00, 0x80, }, }, { "crop (-100, -100, 2, 2)", image.Rect(-100, -100, 2, 2), image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 3, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0x00, 0x80, 0x00, }, }, { "crop (-100, -100, 100, 100)", image.Rect(-100, -100, 100, 100), image.Rect(-1, -1, 4, 2), image.Rect(0, 0, 5, 3), []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, []uint8{ 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0xB0, 0xA0, 0xB0, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, }, }, } for _, d := range testData { src := image.NewGray(d.srcb) src.Pix = d.srcPix f := Crop(d.r) dst := image.NewGray(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } } func TestCropToSize(t *testing.T) { testData := []struct { desc string w, h int anchor Anchor srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "crop to size (0, 0, center)", 0, 0, CenterAnchor, image.Rect(-1, -1, 4, 4), image.Rect(0, 0, 0, 0), []uint8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, }, []uint8{}, }, { "crop to size (3, 3, center)", 3, 3, CenterAnchor, image.Rect(-1, -1, 4, 4), image.Rect(0, 0, 3, 3), []uint8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, }, []uint8{ 0x06, 0x07, 0x08, 0x0b, 0x0c, 0x0d, 0x10, 0x11, 0x12, }, }, { "crop to size (3, 3, top-left)", 3, 3, TopLeftAnchor, image.Rect(-1, -1, 4, 4), image.Rect(0, 0, 3, 3), []uint8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, }, []uint8{ 0x00, 0x01, 0x02, 0x05, 0x06, 0x07, 0x0a, 0x0b, 0x0c, }, }, { "crop to size (3, 3, top)", 3, 3, TopAnchor, image.Rect(-1, -1, 4, 4), image.Rect(0, 0, 3, 3), []uint8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, }, []uint8{ 0x01, 0x02, 0x03, 0x06, 0x07, 0x08, 0x0b, 0x0c, 0x0d, }, }, { "crop to size (3, 3,, top-right)", 3, 3, TopRightAnchor, image.Rect(-1, -1, 4, 4), image.Rect(0, 0, 3, 3), []uint8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, }, []uint8{ 0x02, 0x03, 0x04, 0x07, 0x08, 0x09, 0x0c, 0x0d, 0x0e, }, }, { "crop to size (3, 3, left)", 3, 3, LeftAnchor, image.Rect(-1, -1, 4, 4), image.Rect(0, 0, 3, 3), []uint8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, }, []uint8{ 0x05, 0x06, 0x07, 0x0a, 0x0b, 0x0c, 0x0f, 0x10, 0x11, }, }, { "crop to size (3, 3, right)", 3, 3, RightAnchor, image.Rect(-1, -1, 4, 4), image.Rect(0, 0, 3, 3), []uint8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, }, []uint8{ 0x07, 0x08, 0x09, 0x0c, 0x0d, 0x0e, 0x11, 0x12, 0x13, }, }, { "crop to size (3, 3, bottom-left)", 3, 3, BottomLeftAnchor, image.Rect(-1, -1, 4, 4), image.Rect(0, 0, 3, 3), []uint8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, }, []uint8{ 0x0a, 0x0b, 0x0c, 0x0f, 0x10, 0x11, 0x14, 0x15, 0x16, }, }, { "crop to size (3, 3, bottom)", 3, 3, BottomAnchor, image.Rect(-1, -1, 4, 4), image.Rect(0, 0, 3, 3), []uint8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, }, []uint8{ 0x0b, 0x0c, 0x0d, 0x10, 0x11, 0x12, 0x15, 0x16, 0x17, }, }, { "crop to size (3, 3, bottom-right)", 3, 3, BottomRightAnchor, image.Rect(-1, -1, 4, 4), image.Rect(0, 0, 3, 3), []uint8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, }, []uint8{ 0x0c, 0x0d, 0x0e, 0x11, 0x12, 0x13, 0x16, 0x17, 0x18, }, }, { "crop to size (100, 100, center)", 100, 100, CenterAnchor, image.Rect(-1, -1, 4, 4), image.Rect(0, 0, 5, 5), []uint8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, }, []uint8{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, }, }, } for _, d := range testData { src := image.NewGray(d.srcb) src.Pix = d.srcPix f := CropToSize(d.w, d.h, d.anchor) dst := image.NewGray(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } } func TestRotate(t *testing.T) { testData := []struct { desc string a float32 bg color.Color interp Interpolation srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "rotate 0x0 90 white nearest", 90, color.White, NearestNeighborInterpolation, image.Rect(0, 0, 0, 0), image.Rect(0, 0, 0, 0), []uint8{}, []uint8{}, }, { "rotate 1x1 90 white nearest", 90, color.White, NearestNeighborInterpolation, image.Rect(-1, -1, 0, 0), image.Rect(0, 0, 1, 1), []uint8{0x80}, []uint8{0x80}, }, { "rotate 3x3 -90 white nearest", -90, color.White, NearestNeighborInterpolation, image.Rect(-1, -1, 2, 2), image.Rect(0, 0, 3, 3), []uint8{ 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, }, []uint8{ 0x70, 0x40, 0x10, 0x80, 0x50, 0x20, 0x90, 0x60, 0x30, }, }, { "rotate 3x3 -90 white linear", -90, color.White, LinearInterpolation, image.Rect(-1, -1, 2, 2), image.Rect(0, 0, 3, 3), []uint8{ 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, }, []uint8{ 0x70, 0x40, 0x10, 0x80, 0x50, 0x20, 0x90, 0x60, 0x30, }, }, { "rotate 3x3 45 black nearest", 45, color.Black, NearestNeighborInterpolation, image.Rect(-1, -1, 2, 2), image.Rect(0, 0, 5, 5), []uint8{ 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, }, []uint8{ 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x20, 0x30, 0x60, 0x00, 0x10, 0x10, 0x50, 0x90, 0x90, 0x00, 0x40, 0x70, 0x80, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, }, }, { "rotate 5x5 45 black linear", 45, color.Black, LinearInterpolation, image.Rect(-1, -1, 4, 4), image.Rect(0, 0, 8, 8), []uint8{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }, []uint8{ 0x00, 0x00, 0x00, 0x26, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xe0, 0xe0, 0x2c, 0x00, 0x00, 0x00, 0x2c, 0xe0, 0xff, 0xff, 0xe0, 0x2c, 0x00, 0x26, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x26, 0x26, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x26, 0x00, 0x2c, 0xe0, 0xff, 0xff, 0xe0, 0x2c, 0x00, 0x00, 0x00, 0x2c, 0xe0, 0xe0, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x26, 0x00, 0x00, 0x00, }, }, { "rotate 5x5 45 black cubic", 45, color.Black, CubicInterpolation, image.Rect(-1, -1, 4, 4), image.Rect(0, 0, 8, 8), []uint8{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }, []uint8{ 0x00, 0x00, 0x00, 0x23, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xf1, 0xf1, 0x28, 0x00, 0x00, 0x00, 0x28, 0xe3, 0xff, 0xff, 0xe3, 0x28, 0x00, 0x23, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xf1, 0x23, 0x23, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xf1, 0x23, 0x00, 0x28, 0xe3, 0xff, 0xff, 0xe3, 0x28, 0x00, 0x00, 0x00, 0x28, 0xf1, 0xf1, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x23, 0x00, 0x00, 0x00, }, }, } for _, d := range testData { src := image.NewGray(d.srcb) src.Pix = d.srcPix f := Rotate(d.a, d.bg, d.interp) dst := image.NewGray(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } } gift-0.2.0/utils.go000066400000000000000000000074061513354670200141460ustar00rootroot00000000000000package gift import ( "image" "image/draw" "math" "sync" ) // parallelize parallelizes the data processing. func parallelize(procs int, start, stop int, fn func(start, stop int)) { var wg sync.WaitGroup splitRange(start, stop, procs, func(pstart, pstop int) { wg.Add(1) go func() { defer wg.Done() fn(pstart, pstop) }() }) wg.Wait() } // splitRange splits a range into n parts and calls a function for each of them. func splitRange(start, stop, n int, fn func(pstart, pstop int)) { count := stop - start if count < 1 { return } if n < 1 { n = 1 } if n > count { n = count } div := count / n mod := count % n for i := 0; i < n; i++ { fn( start+i*div+minint(i, mod), start+(i+1)*div+minint(i+1, mod), ) } } func absf32(x float32) float32 { if x < 0 { return -x } return x } func minf32(x, y float32) float32 { if x < y { return x } return y } func maxf32(x, y float32) float32 { if x > y { return x } return y } func powf32(x, y float32) float32 { return float32(math.Pow(float64(x), float64(y))) } func logf32(x float32) float32 { return float32(math.Log(float64(x))) } func expf32(x float32) float32 { return float32(math.Exp(float64(x))) } func sincosf32(a float32) (float32, float32) { sin, cos := math.Sincos(math.Pi * float64(a) / 180) return float32(sin), float32(cos) } func floorf32(x float32) float32 { return float32(math.Floor(float64(x))) } func sqrtf32(x float32) float32 { return float32(math.Sqrt(float64(x))) } func minint(x, y int) int { if x < y { return x } return y } func maxint(x, y int) int { if x > y { return x } return y } func sort(data []float32) { n := len(data) if n < 2 { return } if n <= 20 { for i := 1; i < n; i++ { x := data[i] j := i - 1 for ; j >= 0 && data[j] > x; j-- { data[j+1] = data[j] } data[j+1] = x } return } i := 0 j := n - 1 x := data[n/2] for i <= j { for data[i] < x { i++ } for data[j] > x { j-- } if i <= j { data[i], data[j] = data[j], data[i] i++ j-- } } if j > 0 { sort(data[:j+1]) } if i < n-1 { sort(data[i:]) } } // createTempImage creates a temporary image. func createTempImage(r image.Rectangle) draw.Image { return image.NewNRGBA64(r) } // isOpaque checks if the given image is opaque. func isOpaque(img image.Image) bool { type opaquer interface { Opaque() bool } if o, ok := img.(opaquer); ok { return o.Opaque() } return false } // genDisk generates a disk-shaped kernel. func genDisk(ksize int) []float32 { if ksize%2 == 0 { ksize-- } if ksize < 1 { return []float32{} } disk := make([]float32, ksize*ksize) kcenter := ksize / 2 for i := 0; i < ksize; i++ { for j := 0; j < ksize; j++ { x := kcenter - i y := kcenter - j r := math.Sqrt(float64(x*x + y*y)) if r <= float64(ksize/2) { disk[j*ksize+i] = 1 } } } return disk } // copyimage copies an image from src to dst. func copyimage(dst draw.Image, src image.Image, options *Options) { if options == nil { options = &defaultOptions } srcb := src.Bounds() dstb := dst.Bounds() pixGetter := newPixelGetter(src) pixSetter := newPixelSetter(dst) parallelize(options.Workers, srcb.Min.Y, srcb.Max.Y, func(start, stop int) { for srcy := start; srcy < stop; srcy++ { for srcx := srcb.Min.X; srcx < srcb.Max.X; srcx++ { dstx := dstb.Min.X + srcx - srcb.Min.X dsty := dstb.Min.Y + srcy - srcb.Min.Y pixSetter.setPixel(dstx, dsty, pixGetter.getPixel(srcx, srcy)) } } }) } type copyimageFilter struct{} func (p *copyimageFilter) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { dstBounds = image.Rect(0, 0, srcBounds.Dx(), srcBounds.Dy()) return } func (p *copyimageFilter) Draw(dst draw.Image, src image.Image, options *Options) { copyimage(dst, src, options) } gift-0.2.0/utils_test.go000066400000000000000000000137111513354670200152010ustar00rootroot00000000000000package gift import ( "bytes" "image" "image/color" "testing" ) func TestParallelize(t *testing.T) { for _, e := range []int{5, 1} { for _, n := range []int{0, 1, 5, 10, 50, 100, 500, 1000, 5000} { for _, p := range []int{1, 2, 4, 8, 16, 32, 64, 128} { if !testParallelizeN(e, n, p) { t.Fatalf("test [e=%v n=%d p=%d] failed", e, n, p) } } } } } func testParallelizeN(workers int, n, procs int) bool { data := make([]int, n) parallelize(workers, 0, n, func(start, stop int) { for i := start; i < stop; i++ { data[i]++ } }) for i := range n { if data[i] != 1 { return false } } return true } func TestSplitRange(t *testing.T) { for count := range 100 { for procs := range 100 { start := -55 var parts [][2]int splitRange(start, start+count, procs, func(start, stop int) { parts = append(parts, [2]int{start, stop}) }) wantLen := max(procs, 1) if wantLen > count { wantLen = count } if len(parts) != wantLen { t.Fatalf("test [count=%d procs=%d] got len(parts) %d want %d", count, procs, len(parts), wantLen) } data := make([]int, count) for _, p := range parts { for i := p[0]; i < p[1]; i++ { data[i-start]++ } } for i := range data { if data[i] != 1 { t.Fatalf("test [count=%d procs=%d] got data[%d] == %d want 1", count, procs, i, data[i]) } } } } } func TestTempImageCopy(t *testing.T) { tmp1 := createTempImage(image.Rect(-1, -2, 1, 2)) if !tmp1.Bounds().Eq(image.Rect(-1, -2, 1, 2)) { t.Error("unexpected temp image bounds") } tmp2 := createTempImage(image.Rect(-3, -4, 3, 4)) if !tmp2.Bounds().Eq(image.Rect(-3, -4, 3, 4)) { t.Error("unexpected temp image bounds") } copyimage(tmp1, tmp2, nil) } func TestSort(t *testing.T) { testData := []struct { a, b []float32 }{ { []float32{}, []float32{}, }, { []float32{0.1}, []float32{0.1}, }, { []float32{0.4, 0.2, 0.5, -0.5, 0.3, 0.0, 0.1}, []float32{-0.5, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5}, }, { []float32{-10, 10, -20, 20, -30, 30}, []float32{-30, -20, -10, 10, 20, 30}, }, { []float32{ 0.60, 0.94, 0.66, 0.44, 0.42, 0.69, 0.07, 0.16, 0.10, 0.30, 0.52, 0.81, 0.21, 0.38, 0.32, 0.47, 0.28, 0.29, 0.68, 0.22, 0.20, 0.36, 0.57, 0.86, 0.29, 0.30, 0.75, 0.21, 0.87, 0.70, }, []float32{ 0.07, 0.10, 0.16, 0.20, 0.21, 0.21, 0.22, 0.28, 0.29, 0.29, 0.30, 0.30, 0.32, 0.36, 0.38, 0.42, 0.44, 0.47, 0.52, 0.57, 0.60, 0.66, 0.68, 0.69, 0.70, 0.75, 0.81, 0.86, 0.87, 0.94, }, }, } for _, d := range testData { sort(d.a) for i := range d.a { if d.a[i] != d.b[i] { t.Errorf("sort failed: %#v", d.a) } } } } func TestDisk(t *testing.T) { testData := []struct { ksize int k []float32 }{ { -5, []float32{}, }, { 0, []float32{}, }, { 1, []float32{1}, }, { 2, []float32{1}, }, { 3, []float32{ 0, 1, 0, 1, 1, 1, 0, 1, 0, }, }, { 4, []float32{ 0, 1, 0, 1, 1, 1, 0, 1, 0, }, }, { 5, []float32{ 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, }, }, { 6, []float32{ 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, }, }, { 7, []float32{ 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, }, }, } for _, d := range testData { disk := genDisk(d.ksize) for i := range disk { if disk[i] != d.k[i] { t.Errorf("gen disk failed: %d %#v", d.ksize, disk) } } } } type customImage struct{} func (customImage) ColorModel() color.Model { return color.GrayModel } func (customImage) Bounds() image.Rectangle { return image.Rectangle{} } func (customImage) At(x, y int) color.Color { return color.Gray{} } func TestIsOpaque(t *testing.T) { type opqt struct { img image.Image opaque bool } var testData []opqt testData = append(testData, opqt{customImage{}, false}) testData = append(testData, opqt{image.NewNRGBA(image.Rect(0, 0, 1, 1)), false}) testData = append(testData, opqt{image.NewNRGBA64(image.Rect(0, 0, 1, 1)), false}) testData = append(testData, opqt{image.NewRGBA(image.Rect(0, 0, 1, 1)), false}) testData = append(testData, opqt{image.NewRGBA64(image.Rect(0, 0, 1, 1)), false}) testData = append(testData, opqt{image.NewGray(image.Rect(0, 0, 1, 1)), true}) testData = append(testData, opqt{image.NewGray16(image.Rect(0, 0, 1, 1)), true}) testData = append(testData, opqt{image.NewYCbCr(image.Rect(0, 0, 1, 1), image.YCbCrSubsampleRatio444), true}) testData = append(testData, opqt{image.NewAlpha(image.Rect(0, 0, 1, 1)), false}) img1 := image.NewNRGBA(image.Rect(0, 0, 1, 1)) img1.Set(0, 0, color.NRGBA{0x00, 0x00, 0x00, 0xff}) testData = append(testData, opqt{img1, true}) img2 := image.NewNRGBA64(image.Rect(0, 0, 1, 1)) img2.Set(0, 0, color.NRGBA{0x00, 0x00, 0x00, 0xff}) testData = append(testData, opqt{img2, true}) img3 := image.NewRGBA(image.Rect(0, 0, 1, 1)) img3.Set(0, 0, color.NRGBA{0x00, 0x00, 0x00, 0xff}) testData = append(testData, opqt{img3, true}) img4 := image.NewRGBA64(image.Rect(0, 0, 1, 1)) img4.Set(0, 0, color.NRGBA{0x00, 0x00, 0x00, 0xff}) testData = append(testData, opqt{img4, true}) imgp1 := image.NewPaletted(image.Rect(0, 0, 1, 1), []color.Color{color.NRGBA{0x00, 0x00, 0x00, 0xff}}) imgp1.SetColorIndex(0, 0, 0) testData = append(testData, opqt{imgp1, true}) imgp2 := image.NewPaletted(image.Rect(0, 0, 1, 1), []color.Color{color.NRGBA{0x00, 0x00, 0x00, 0xfe}}) imgp2.SetColorIndex(0, 0, 0) testData = append(testData, opqt{imgp2, false}) for _, d := range testData { isop := isOpaque(d.img) if isop != d.opaque { t.Errorf("isOpaque failed %#v, %v", d.img, isop) } } } func checkBoundsAndPix(b1, b2 image.Rectangle, pix1, pix2 []uint8) bool { if !b1.Eq(b2) { return false } if !bytes.Equal(pix1, pix2) { return false } return true }