+
+ 给一个矩形填充颜色:
+
+ 使用 Draw方法的逻辑效果图:
+
+
+
+ 代码:
+
+~~~go
+ m := image.NewRGBA(image.Rect(0, 0, 640, 480))
+
+ blue := color.RGBA{0, 0, 255, 255}
+
+ draw.Draw(m, m.Bounds(), &image.Uniform{blue}, image.ZP, draw.Src)
+~~~
+
+ 拷贝图片的一部分效果特效如下:
+
+
+
+ 相关代码:
+
+~~~go
+ r := image.Rectangle{dp, dp.Add(sr.Size())} // 获得更换区域
+
+ draw.Draw(dst, r, src, sr.Min, draw.Src)
+~~~
+
+ 如果是复制整个图片,则更简单:
+
+~~~go
+ sr = src.Bounds() // 获取要复制图片的尺寸
+
+ r := sr.Sub(sr.Min).Add(dp) // 目标图的要剪切区域
+
+ draw.Draw(dst, r, src, sr.Min, draw.Src)
+~~~
+
+ 图片滚动效果如下图:
+
+ 
+
+ 假设我们需要把图片 m 上移20个像素.
+
+ 相关代码:
+
+~~~go
+ b := m.Bounds()
+
+ p := image.Pt(0, 20)
+
+ // 注意,尽管第二个参数是b,但由于剪切,有效矩形变小了。
+
+ draw.Draw(m, b, m, b.Min.Add(p), draw.Src)
+
+ dirtyRect := b.Intersect(image.Rect(b.Min.X, b.Max.Y-20, b.Max.X, b.Max.Y))
+~~~
+
+ 把一个图片转成RGBA格式,效果图:
+
+
+
+ 相关代码:
+
+~~~go
+ b := src.Bounds()
+
+ m := image.NewRGBA(b)
+
+ draw.Draw(m, b, src, b.Min, draw.Src)
+~~~
+
+ 通过蒙版画特效效果图
+
+
+
+相关代码
+
+~~~go
+ type circle struct {
+
+ p image.Point
+
+ r int
+
+ }
+
+ func (c *circle) ColorModel() color.Model {
+
+ return color.AlphaModel
+
+ }
+
+ func (c *circle) Bounds() image.Rectangle {
+
+ return image.Rect(c.p.X-c.r, c.p.Y-c.r, c.p.X+c.r, c.p.Y+c.r)
+
+ }
+
+
+
+ func (c *circle) At(x, y int) color.Color {
+
+ xx, yy, rr := float64(x-c.p.X)+0.5, float64(y-c.p.Y)+0.5, float64(c.r)
+
+ if xx*xx+yy*yy < rr*rr {
+
+ return color.Alpha{255}
+
+ }
+
+ return color.Alpha{0}
+
+ }
+
+ draw.DrawMask(dst, dst.Bounds(), src, image.ZP, &circle{p, r}, image.ZP, draw.Over)
+~~~
+
+注意,一个image对象只需要实现下面几个就可,这也就是Go接口强大的地方.
+
+~~~go
+ type Image interface {
+
+ // 返回图像的颜色模型。
+
+ ColorModel() color.Model
+
+ // Bounds返回一个可以返回非零颜色的域。
+
+ // 边界不一定包含点(0,0)。
+
+ Bounds() Rectangle
+
+ // 返回(x, y)处像素的颜色。
+
+ // At(Bounds().Min.X, Bounds().Min.Y) 返回网格左上角的像素的值。
+
+ // At(Bounds().Max.X-1, Bounds().Max.Y-1) 返回右下角的像素的值。
+
+ At(x, y int) color.Color
+
+ }
+~~~
+
+ 画一个字体
+
+ 效果图,画一个蓝色背景的字体。
+
+
+
+ 相关伪代码:
+
+~~~go
+ src := &image.Uniform{color.RGBA{0, 0, 255, 255}}
+
+ mask := theGlyphImageForAFont()
+
+ mr := theBoundsFor(glyphIndex)
+
+ draw.DrawMask(dst, mr.Sub(mr.Min).Add(p), src, image.ZP, mask, mr.Min, draw.Over)
+~~~
+
+# image/color包用法:
+
+ Color包实现了一个基本的颜色库:color是一个接口,它定义了可以被视为颜色的任何类型的最小方法集:可以转换为红色、绿色、蓝色和alpha值的颜色。转换可能是有损的,例如从CMYK或YCbCr颜色空间转换。其代码演示如下:
+
+~~~go
+type Color interface {
+
+ RGBA() (r, g, b, a uint32)
+
+}
+~~~
+
+ RGBA返回字母预先乘上的红色、绿色、蓝色和颜色的alpha值。每个值的范围都在[0,0xFFFF]内,但是由uint32表示,因此乘以一个直到0xFFFF的混合因子不会溢出。
+
+ 关于返回值有三个重要的点:首先,红色,绿色和蓝色是先预乘alpha:完全饱和的红色也是25%透明,由RGBA返回75%。第二,容器有16位:100%的红色是由RGBA返回一个65535的r的值,而不是255,所以从CMYK或YCbCr转换没有损耗。第三,返回的类型是uint32,将最大值设置为65535以保证两个值相乘不会溢出。
+
+ Image/color包还定义了许多实现color接口的具体类型。例如,RGBA是一个结构体,它代表了经典的“每个容器8位颜色”,代码如下:
+
+~~~go
+type RGBA struct {
+
+ R, G, B, A uint8
+
+}
+~~~
+
+ 不过要注意的是:RGBA的R字段是8位字符预乘范围[0,255]的颜色。RGBA通过将该值乘以0x101来满足颜色接口,从而在范围[0,65535]内生成一个16位的颜色。类似地,NRGBA结构类型表示一种8位的没有alpha预乘的颜色,就像PNG图像格式所使用的那样。当直接操作'NRGBA '的字段时,其值没有预乘alpha,但当调用RGBA方法时,返回值要预乘alpha。
+
+# Image/palette包用法:
+
+ 调色板这个包为提供为图像库提供了一个标准的调色板。
+
+Image/color/palette/gen.go:运行程序时会生成palette .go文件。
+
+Image/color/palette/generate.go:在生成palette.go文件时会自动运行。
+
+Image/color/palette/palette.go:定义了两种调色板——Plan9和WebSafe:
+
+ Plan9是一个256色的调色板,将24位RGB空间分割成4×4×4的细分,每个子立方体有4个阴影。与WebSafe相比,其想法是通过将颜色立方体切成更少的单元来降低颜色分辨率,并使用额外的空间来增加强度分辨率。这样就得到了16个灰色阴影(4个灰色子立方体,每个子立方体中有4个样本),每种原色和副色的13个阴影(3个子立方体,4个样本加上黑色),并合理地选择了覆盖颜色立方体其余部分的颜色。其优点是可以更好地表示连续色调。
+
+ WebSafe是一个216色的调色板,由于Netscape Navigator的早期版本而流行起来。它也被称为网景颜色多维数据集。
+
+# Image/gif包用法:
+
+ gif包实现了gif图片的解码及编码。
+
+~~~go
+func Decode(r io.Reader) (image.Image, error) //Decode从r中读取一个GIF图像,然后返回的image.Image是第一个嵌入的图。
+
+func DecodeConfig(r io.Reader) (image.Config, error) //DecodeConfig不需要解码整个图像就可以返回全局的颜色模型和GIF图片的尺寸。
+
+type Config struct {
+
+ ColorModel color.Model
+
+ Width, Height int
+
+}
+
+//Config返回图像的颜色model和尺寸
+func Encode(w io.Writer, m image.Image, o *Options) error //将图片m按照gif模式写入w中
+
+type Options struct {
+
+ // NumColors是图片中使用颜色的最大值,它的范围是1-256
+
+ NumColors int
+
+ // Quantizer经常被用来通过NumColors产生调色板,palette.Plan9 被用来替代nil Quantizer
+
+ Quantizer draw.Quantizer
+
+ // Drawer i用于将源图片转化为期望的调色板, draw.FloydSteinberg 用来替代一个空 Drawer.
+
+ Drawer draw.Drawer
+
+}
+func EncodeAll(w io.Writer, g *GIF) error //将图片按照帧与帧之间指定的循环次数和时延写入w中
+
+type GIF struct {
+
+ Image []*image.Paletted // 连续的图片
+
+ Delay []int // 连续的延迟时间,每一帧单位都是百分之一秒,delay中数值表示其两个图像动态展示的时间间隔
+
+ LoopCount int // 循环次数,如果为0则一直循环。
+
+}
+
+func DecodeAll(r io.Reader) (*GIF, error) //DecodeAll 从r上读取一个GIF图片,并且返回顺序的帧和时间信息
+~~~
+
+# image/jpeg包用法:
+
+ jpeg包实现了jpeg图片的编码和解码。
+
+~~~go
+func Decode(r io.Reader) (image.Image, error) //Decode读取一个jpeg文件,并将他作为image.Image返回
+
+ func DecodeConfig(r io.Reader) (image.Config, error) //无需解码整个图像,DecodeConfig变能够返回整个图像的尺寸和颜色(Config具体定义查看gif包中的定义)
+
+ func Encode(w io.Writer, m image.Image, o *Options) error //按照4:2:0的基准格式将image写入w中,如果options为空的话,则传递默认参数
+
+type Options struct {
+ Quality int
+}//Options是编码参数,它的取值范围是1-100,值越高质量越好
+
+type FormatError //用来报告一个输入不是有效的jpeg格式
+
+type FormatError string
+
+func (e FormatError) Error() string
+
+type Reader //不推荐使用Reader
+
+type Reader interface {
+ io.ByteReader
+ io.Reader
+}
+
+type UnsupportedError
+
+func (e UnsupportedError) Error() string //报告输入使用一个有效但是未实现的jpeg功能
+~~~
+
+# image/png包用法:
+
+ image/png实现了png图像的编码和解码。
+
+ png和jpeg实现方法基本相同,都是对图像进行了编码和解码操作。
+
+~~~go
+func Decode(r io.Reader) (image.Image, error) //Decode从r中读取一个图片,并返回一个image.image,返回image类型取决于png图片的内容
+
+func DecodeConfig(r io.Reader) (image.Config, error) //无需解码整个图像变能够获取整个图片的尺寸和颜色
+
+func Encode(w io.Writer, m image.Image) error //Encode将图片m以PNG的格式写到w中。任何图片都可以被编码,但是哪些不是image.NRGBA的图片编码可能是有损的。
+
+type FormatError
+
+func (e FormatError) Error() string //FormatError会提示一个输入不是有效PNG的错误。
+
+~~~
+
+ 由此可见,png和jpeg使用方法类似,只是两种不同的编码和解码方式。
+
+# 应用如下:
+
+## 1.生成图片:
+
+~~~go
+package main
+
+import "image"import "image/color"import "image/png"import "os"
+
+func main() {
+
+ //生成一个100X50的图像。
+
+ img := image.NewRGBA(image.Rect(0, 0, 100, 50))
+
+ // 在 (2, 3)处画一个红点。
+
+ img.Set(2, 3, color.RGBA{255, 0, 0, 255})
+
+ // 保存到out.png
+
+ f, _ := os.OpenFile("out.png", os.O_WRONLY|os.O_CREATE, 0600)
+
+ defer f.Close()
+
+ png.Encode(f, img)
+
+}
+~~~
+
+运行结果,就是生成了一张png文件。
+
+## 2.生成复杂色彩的图片:
+
+~~~go
+package main
+
+import (
+
+ "fmt"
+
+ "image"
+
+ "image/color"
+
+ "image/png"
+
+ "math"
+
+ "os"
+
+)
+
+type Circle struct {
+
+ X, Y, R float64
+
+}
+
+func (c *Circle) Brightness(x, y float64) uint8 {
+
+ var dx, dy float64 = c.X - x, c.Y - y
+
+ d := math.Sqrt(dx*dx+dy*dy) / c.R
+
+ if d > 1 {
+
+ return 0
+
+ } else {
+
+ return 255
+
+ }
+
+}
+
+func main() {
+
+ var w, h int = 280, 240
+
+ var hw, hh float64 = float64(w / 2), float64(h / 2)
+
+ r := 40.0
+
+ θ := 2 * math.Pi / 3
+
+ cr := &Circle{hw - r*math.Sin(0), hh - r*math.Cos(0), 60}
+
+ cg := &Circle{hw - r*math.Sin(θ), hh - r*math.Cos(θ), 60}
+
+ cb := &Circle{hw - r*math.Sin(-θ), hh - r*math.Cos(-θ), 60}
+
+ m := image.NewRGBA(image.Rect(0, 0, w, h))
+
+ for x := 0; x < w; x++ {
+
+ for y := 0; y < h; y++ {
+
+ c := color.RGBA{
+
+ cr.Brightness(float64(x), float64(y)),
+
+ cg.Brightness(float64(x), float64(y)),
+
+ cb.Brightness(float64(x), float64(y)),
+
+ 255,
+
+ }
+
+ m.Set(x, y, c)
+
+ }
+
+ }
+
+ f, err := os.OpenFile("rgb.png", os.O_WRONLY|os.O_CREATE, 0600)
+
+ if err != nil {
+
+ fmt.Println(err)
+
+ return
+
+ }
+
+ defer f.Close()
+
+ png.Encode(f, m)
+
+}
+~~~
+
+运行结果:
+
+
+## 3.获取一张图片的尺寸并生成略缩图
+
+~~~go
+import (
+ "fmt"
+ "github.com/nfnt/resize"
+ "image"
+ _ "image/gif"
+ _ "image/jpeg"
+ "image/png"
+ "math"
+ "os"
+ "path/filepath"
+ "time"
+)
+
+const DEFAULT_MAX_WIDTH float64 = 320
+const DEFAULT_MAX_HEIGHT float64 = 240
+
+// 计算图片缩放后的尺寸
+func calculateRatioFit(srcWidth, srcHeight int) (int, int) {
+ ratio := math.Min(DEFAULT_MAX_WIDTH/float64(srcWidth), DEFAULT_MAX_HEIGHT/float64(srcHeight))
+ return int(math.Ceil(float64(srcWidth) * ratio)), int(math.Ceil(float64(srcHeight) * ratio))
+}
+
+// 生成缩略图
+func makeThumbnail(imagePath, savePath string) (string, error) {
+
+ file, _ := os.Open(imagePath)
+ defer file.Close()
+
+ img, _, err := image.Decode(file)
+ if err != nil {
+ return err
+ }
+
+ b := img.Bounds()
+ width := b.Max.X
+ height := b.Max.Y
+
+ w, h := calculateRatioFit(width, height)
+
+ fmt.Println("width = ", width, " height = ", height)
+ fmt.Println("w = ", w, " h = ", h)
+
+ // 调用resize库进行图片缩放
+ m := resize.Resize(uint(w), uint(h), img, resize.Lanczos3)
+
+ // 需要保存的文件
+ imgfile, _ := os.Create(savePath)
+ defer imgfile.Close()
+
+ // 以PNG格式保存文件
+ err = png.Encode(imgfile, m)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+~~~
+
+## 4.两张图片上下排列合成为一张新图片
+
+~~~go
+package main
+
+import (
+ "github.com/nfnt/resize"
+ "image"
+ "image/draw"
+ "image/jpeg"
+ "log"
+ "math"
+ "os"
+)
+
+const MaxWidth float64 = 600
+
+func fixSize(img1W, img2W int) (new1W, new2W int) {
+ var ( //为了方便计算,将两个图片的宽转为 float64
+ img1Width, img2Width = float64(img1W), float64(img2W)
+ ratio1, ratio2 float64
+ )
+
+ minWidth := math.Min(img1Width, img2Width) // 取出两张图片中宽度最小的为基准
+
+ if minWidth > 600 { // 如果最小宽度大于600,那么两张图片都需要进行缩放
+ ratio1 = MaxWidth / img1Width // 图片1的缩放比例
+ ratio2 = MaxWidth / img2Width // 图片2的缩放比例
+
+ // 原宽度 * 比例 = 新宽度
+ return int(img1Width * ratio1), int(img2Width * ratio2)
+ }
+
+ // 如果最小宽度小于600,那么需要将较大的图片缩放,使得两张图片的宽度一致
+ if minWidth == img1Width {
+ ratio2 = minWidth / img2Width // 图片2的缩放比例
+ return img1W, int(img2Width * ratio2)
+ }
+
+ ratio1 = minWidth / img1Width // 图片1的缩放比例
+ return int(img1Width * ratio1), img2W
+}
+
+func main() {
+ file1, _ := os.Open("001.jpg") //打开图片1
+ file2, _ := os.Open("002.jpg") //打开图片2
+ defer file1.Close()
+ defer file2.Close()
+
+ // image.Decode 图片
+ var (
+ img1, img2 image.Image
+ err error
+ )
+ if img1, _, err = image.Decode(file1); err != nil {
+ log.Fatal(err)
+ return
+ }
+ if img2, _, err = image.Decode(file2); err != nil {
+ log.Fatal(err)
+ return
+ }
+ b1 := img1.Bounds()
+ b2 := img2.Bounds()
+ new1W, new2W := fixSize(b1.Max.X, b2.Max.X)
+
+ // 调用resize库进行图片缩放(高度填0,resize.Resize函数中会自动计算缩放图片的宽高比)
+ m1 := resize.Resize(uint(new1W), 0, img1, resize.Lanczos3)
+ m2 := resize.Resize(uint(new2W), 0, img2, resize.Lanczos3)
+
+ // 将两个图片合成一张
+ newWidth := m1.Bounds().Max.X //新宽度 = 随意一张图片的宽度
+ newHeight := m1.Bounds().Max.Y + m2.Bounds().Max.Y // 新图片的高度为两张图片高度的和
+ newImg := image.NewNRGBA(image.Rect(0, 0, newWidth, newHeight)) //创建一个新RGBA图像
+ draw.Draw(newImg, newImg.Bounds(), m1, m1.Bounds().Min, draw.Over) //画上第一张缩放后的图片
+ draw.Draw(newImg, newImg.Bounds(), m2, m2.Bounds().Min.Sub(image.Pt(0, m1.Bounds().Max.Y)), draw.Over) //画上第二张缩放后的图片(这里需要注意Y值的起始位置)
+
+ // 保存文件
+ imgfile, _ := os.Create("003.jpg")
+ defer imgfile.Close()
+ jpeg.Encode(imgfile, newImg, &jpeg.Options{100})
+}
+~~~
+
+ 效果如下所示:
+
+
\ No newline at end of file
diff --git "a/blog/image/images/Draw\346\226\271\346\263\225\351\200\273\350\276\221\346\225\210\346\236\234\345\233\276.png" "b/blog/image/images/Draw\346\226\271\346\263\225\351\200\273\350\276\221\346\225\210\346\236\234\345\233\276.png"
new file mode 100644
index 0000000000000000000000000000000000000000..33e068c02c1d676433650744bdf948e1099057f2
GIT binary patch
literal 1099056
zcmeI*2b3k%dEoKelNbhu8D>Ca7;+S0M1v#{FhdZ7Kp+WLfn%&)YrQM)+GizOYaQ9%
zZp%784!d4C9BaL{k8G`FS&{_?Nl4@@pvg&yFwBs19>S#Vz5jwcJl?zx)BVD&s(;NX
zUiW(yZvAfe$9F?j|M3|g{qWp5JI)Cq%w2Z!2_Fw(+80CUyKwfb_|DoZ{>%5`%Z%S#
zy6nu^arxcZpZlZu{pSDeh}A z^qDcK%WpbFo{1a@@9enlAJ@I(N)l(BiwG_XWFqirEC+Y9wp!>|qJzoCS1X+j@Abt= zH#2AQKZY6E&A-`DNWV}(fnuKA^yzQ)#PNHZ+mdf0N3R^it1e>-oc#|s+}^Ia0ArrW z4;2_qV7K_e0dZ~BP@Ny&=P@PBpL1y`kp9PzUR!SDn+hn9g#dY6hPm83HvI!bgL!6l z@08K66i^^X0W!I>;>rW&niu{g1YPS}G=Jdt3Mim}0__&)8;MK159;w0P@v)hjHB}G zk_1EJc1${H#M%foO+ibI9oj#q(s4fa@ zEMQW%v5D`LK;Zf3pAWa*dTV(2;fKTa+ixEZKm72p!wx$X30?_`ZxIzxK!H&O?z!il zaK{~Y6b;n_4?HmJx8Hv8Z%O&!u2I2i{(*^H&3^#Odil>j`)s)6l1svM*IgIh``-5! zN!)wh^BxnqvR0_&RzQIb0=M6Od-%?GzEg}koN>k(VV7NYc~>IGLns;_L_yD;4=mik zSGzAv
VsReBW)C{Ra%7hZTFJo@OPVa}X6 z;l&qUET)qr2jU#lONfE%)~zcVuc^1rWG*RH?e&+|?YU%Pa{)~1s#f U!Qijj$f z4mzlaft5z_;zkvC=ci-TP5eLs1r$&~0R?gp7#bH-g#%yQ^)rVyQXX5SbROvcs-GG zyG`B#CUSY#&y-6?H~dR4y;R%{#c#kwvop&xK z+dlKmGexWK>8GDA=4CK+$-J~hixw4=aOv_-!H)pLybb1cuph_fYv! TfY_(wy>^Ye2Baus;>)mOuP_uW^-xD*#& zdF7Sjcbz$BTW`H}arfu$yYIf?5>jk=?6JqfbI&~&_?{TXR1J B z-v9phhm%e^smKC}W<(333{i~x>2JRI<|3++-4QW4Hp|?(bHhIS>=Qot!4HP_z3+X2 z+fSJk!ovP!m_)aq{p@E&v?6-0S+k~yPDHys_SmB++i}MoS42?uOPOUl2Cpoflc>kN z{TE(%VYvJ5yTf6J9ac;#A^Nt8*l+FWe-%(5cL7?emtJ~lk MW!`0G*nC` z<2_oUWOKw8wkMw5bkj{mj3OQqZ&-LxC9#i5XT(0TFS5b3@KDP~9(knL_nK?236DSi zc=4c1J|~XQQYE$!m-w1YleqcQpZ>InQ)i!jb`ej>w9-O+qUC$_)mIm{< JT_wpI2^GKm{Nj_m z(KSVqL_pyep1?*RU}Z7}fsI7!i6@>Y5;Ts%_v}j`BS;>9{PAH??5?A$j?W2r1j}1) zxurM{(0s
ZqfNWRC3!P;?hwe);7aCV`M}(H%$EA4wSt$sgC!7-)+R z8vesIr7p=I{_uz4vdb q@HPh2hTZ&90R>7TKsOn2ibfwXid)->EhI<83szzZ zafSva&-tK1ciU~Z6^&9Fpd@f4M F4JcpM;1YM=+rEN$}wpo&ZM+msTFZigDM} zLfvbxy^4VG^Pm4b{P@Q|E)qfl39U%RZ8;VT=b?2-tCVp}UP&1Fob!^T(E?@Vy+ttz zB;c?R3`qhh1HEXR`{N(~c-U>X-HIfT1eEazjz_TKTr31F7QUx7ngS%(@uMI8C|q&H z6-Ajo^O?_tkAC!{#qm;kiyi%s0uvHg@sUdpeD_>{3GL=a9T%Ws#_u$7jh-_mkCANA z&?E*CLm0cH;Yz}G-g)PRi!Z*o*oP;KA92JHMJywJa2LUiH{MvRByKFkIg%t|8x39J z7!S5&JeG&Q5vy2e43kJQr-bs5WTn`f8j+2$tJvx7|FA7FnliA>SdC3$94q@!hGol^ z6^SD;l7x=9dGg687iA!>ay&fP-lZM_CUy0w=M7g$BDG}6lA>EbO=KfkB2X}#O7cc< zVL0@ZQ%)&bm;?ldEcl!rIwp@0L}+2MustnQ0?cu-l}S)aEnxN~(2@w!YsN4v`!fui z7S2sT |P9RIc>*yZDUraK5w `7vE+G(eSk9_1K#gq*ixhzaA zp>fL;5*mVR%ah1YKmGI~kt61D9Fj)<6a#UI=_14%&P{I| TT zd8HLiQpYRDq|79R9G4{p@$^005V+Z%p=4U$42uxZmo8me1aGc`;~3nMxUUM7S0KeR zhA)W?%mF^~$Rmr9h7?C={L$ECxRWU&M<0E3(Kuz>)O&^iap8ai4k)I1FdR!mmeGn6 zPB@{6AsmmGL#!h%kv#GqqZ%ZGDGsqsigzjgrPtA<)90HSm(sb?{(MgyWOb>hfHhx( zdZ)XcUv`2X$rdZYEG>MUh5~pc$xB111T7W<9?21(6VT{oOF^tL5Yg+#oH&v-TC8kG zz@=52CJhr5)4m*={Ta$2!6f)HftiGip w5a^>4SamU4; zL0aG>s3vhq%vS} SRJN$y?(w7@8%SBbc%@CUSgDOP2(U@)4M6 zRWrA4Wt^DIN-*V-C~0^&?ay&ZAUQUzX39*NNGw_DO=OwKwG FB?nsgjmyChoYpMQR_l2~yE7{QRh zNQ;?XK$1IJwA`&q5=L-sTxih}3>gCEc~RUk##1oqo#R ~V?`n3WIlv5zZvlNS3T?LIve*X_S #(R8Ej~nynh-pj#p;wMZCQ~|yH4Nc?>|-A*?w)Nd3tu;W-*~>1Xi|>m zq_S~4zgA!(0%b|${{60N?%gmKU?LahHr*GXwadH`5-(b;-0j7jHG(Kf6)jeVL- f9^=7L7C!5qegm<{pg)b2^q&C_7G>d zbChFT8526 l0KIeExIinF z;n8D`Ii?sAC2*2F5d>LCxJdd4UffpSDsb^$TIr=rb6c3l!sKIyUiq4!Nibwvk~Lb~ z^ym>_DFYLkc}OU|fjo|ciOeL149B=Apg{En7=ooC$xT$;e8uxF8FFnk4>)P0L@vdw z^nQv-yb_a`hfA`@^b(FuBbBKhj2^Hr=jK?%yL2-}Iu@_=$nhBsUp{A_=5sb~KibzE zCyjDUX8+NS>-*&sFp(=?on>2Mf=Rl2l|m9|2vh_-{wg$c>X_3;l1ETX3jr_%J&r-^ zmte>?d`|*K;ABa`HtoyjB#f-7ckZ}&0|mW*JS&O^5ig35Sz)-9-Z_)GB Orhy z;XQf*Nf^1Ag6DD4_+;UHoP#-b%qynxOLCbK#bTog{D*Thbj&NUl^efkyrz)~t|67J zG0sll&~8#v0Ta2BR@|l(n_p~NZmcQbH1E$gsfEWY-#0Jm^Ty*4$ml&II5H=W`Ec}r z5yS{w1R91@`ExaVo|eYr6DXNXOv{#q#EYIbf?NuCBw*?B0|c <$zuxLxfKJGIOa)pCG{ynqQe#|6dyv!+lX%7)L!rb3 z{=6TtiK!Yi@JQ^~pIAg=laT|GCFbDL(@)G;8RrGFKZzUhj%gsoM5dOo5{GD{GQ`R` zSr`#u-Y{{IIlzn_@TertNAksfOa~!hOmVmQ8hAg&UOsF5oN^I=8Rei?ka>I@pE7Vg zDWRndCUxm2qS~*0TYu_>@0i(DyON8mBN7mG=sx3>DABy|UfPDQn >x14fIYl?i#CMGhHozX;PAEF#xc0?G?l@>muxylS _ZnHSsPt<#2&_2xjT!N zB5{dqisP{lU-S3Eh-C~*oO|xMMf{>X#6RK^*&{KHjE?g*#zXWu2k)n~u|~+&n7~I? z%7j3&Mq(o6W_!9Oxy_bqajA!ZiChipnPwc5J<_u}QuDF#(g_X(DUuwLGq!1L(xv`= zy1ED!Y{PrJ67=}PfNW0_F*R8kZ(#crbV%w*sz}h-H!XC(kz}zye}ZCVYzh;|_@3ZM zz#}m6SF1_LC>tw*k>gWt%Ad;1^%8Ws6N9e8Z-4vSMOPmQC-0lcC3#;JD4zho-^2@k z_lawbzx(NGhy}z5y3x2Dm4u6~Fdjrn<1RgPj--&|(Pc(MlSUxjdBh}E;v27Y_Y<2^ zT;e@q5f8v5Q6zaw<=_v(601ng(nINJkP^#CwzzelyTe#0C)Yt48W& Xgr6g7aC;}cWO+F(S@g8FqByzkm#=x^g(n3&X z8_G%$N;8!y7yDBl-X|esAy{!u1W*DNy>zUN!H}Ry;?qXBF4NxC+-ufOJuyjsj;5 z?fF90<^rTdZBd+`L9F0+p7_veNpXWeN=+=G!AXKe4_SJ~5%Gaz5>JRbti%#x3$c?J z$-ay-un)&1RuWrCuDCOTxRuI4qmkG~tR(hv#{&siDhu0l4jRWaSUFFMbLkrRBh@S< zaOpPw^cmZefHES&_47G%TGCw=xUi=3r2TxYu0UUGooqZ)s=C)(yDLjW5+q`@ `%`dtx~>c;d8cQ t8QBVab`96|F4AF{vv{O<7I_ z6i`3`1r$)ANx(#|3B+#|P(T3%6i`5cvIv;Sm8GUErveHnpnw7jD9|MEfzRA?^^8A# TqqyyP*@+)L;oPO4{p$Y*r4Hw> literal 0 HcmV?d00001 diff --git "a/blog/image/images/RGBA\346\240\274\345\274\217\350\275\254\346\215\242.png" "b/blog/image/images/RGBA\346\240\274\345\274\217\350\275\254\346\215\242.png" new file mode 100644 index 0000000000000000000000000000000000000000..f9f064ce454e6c5154387982e184d33352706fce GIT binary patch literal 1267031 zcmeFaON?eomgi;P`}5D=kMQt#W<+LHR@Kx@4>TjOV5DJCqnQQ?A!a1RiUp4?NIj@# z!3GJ5nl%d;u>#EsA=ILUkVc5bNK6BoL87a>tE#IrA~Pc* 3dt_bnFuyOmX2*`1$NAr5=N$V7|MtK2x0ZXidnu*m-~HRa^Y5fo{~uDS{YkgY zoxk+|{==Ibn!oq2{qEoGlK%7VfB0Rl7yi?~{qOx=N*jOATzm8%zxVf3dXRqicmC$z z{rk1l|8DO)wK<7`*C$EMl>9yNKPNvYe_nczo4-Z=7e4P{b+6(;#es?gzo8tc{tx{P z9r&u-6$jo;4m7VN*)yp6i2RSqKl%a+f1CR& 0fVaB6$dH~{Kj(NXZ=5P84gwd zhyKP+ld9tt2d)DLt|t)ni++#%L-HSe0h<=N|1XhGzu NyuNz=Mdg3q`#-5|>-sX *RlveD|I2&9A=$Kg<82|1)I$;m=9h+XC_J>z}i_H;P{s&Skw<@4Zp@ zD{@ix^Ygm%W%T`v>i;t8{yduBwR`fxe3egE&)>EFT%}hK`nSmc2KgHQA9}rk=v9Wk zb^h%1S^DAVhw1w-zyH>g>ayZM#esL312v?=`~3XY&EHD5KD?D`gGyrlLgV>U*ftoy zN~b4}(`iGae7Rna{AOE9 HOC)FCM*6O7C!eVMKZ=@! 3Z{ z6i&4|H2Z#iMje-GE_)v7N?Y}KCEu5h>13LwQ?eD3Y`a#^G}NuL(V$+`P~4x{Hs!~Y zaT<@uX)>9_J9VCg5^kRBXf+$D-EOB=tCboJ-;HAYx@1Nsskkm5UluIx FTdw8c17J@$0J^#yeXbDhSC%B zq!^cAjcpV^mgnu@ZNt9s&RPE?9qjL=-51Z(`S6H7j8bNiGog{1jZW%xduefbIjyX& z#<8=|OHJl>Fp}}MLg!Lc9Fv(bbzGxA%r2UA9*m*SW6TMTBj!V%6W-_bGDWwf4+ |=l?YQ!TI02_rK$9pW_1j!566^_Kka~u{uff_99?K(VyR(Q>!%y1Lxl7VnPPP !xmfM7hG(;oE-q8n`lz5;$uJyYJdUS5p@ z^cE;Vs38!@AXD0=fVgoQjz(!RrjN8E2(_*ZMyV5EX%=8j0C}U~D4m_1rT+O@8Vm+d zOq~IWIHA4<^!9oSX=!OOEiU!|ferYY=?Q}DH#~{12Z!VUDSp}6GL_&+@a^buEtrWP z&jBg)x7L7eo=zx2S5m(}O$UdAba;B6`om$2MX%dRON-Fd>ykUEB?u~kDYOeh$Mk nmr*VCLp3ayL!y$D0hY%B&-@zB?29U}>KMDl)tyVpCpsUjnD0kBW z9}I2F$XDi{?>R~G-zIzm;WdY~bng!r(!%%Zsdo&G`I{)%cO8FSUr;Ky9Aj-99AEx= z;!6Xh>VI#q`T28x{vUp-RB@o -6m;{YHqprH|M&Fg?fz*w`{LIXHYorXY^ z3Qd6{;0^8YE81wP9TaF%xj<(Kco+--U(`FJjRy4yL>qtx0YR$;i0RTx`a2#^0ilC* za?(%7C&z%kKEPLS3(fRN27xcq%F1$DU$3Xp8o&d9F{SMc^(`Y9gB;4+_e^F!7CKgL z*?}_iiXD+BXwn2>@=C1KXu<%2C_IHUfY3Z0A5YS&*ZuVB;4~cpn8&oe0tnq$ou-X7 zv};SX)NW1-;3&9i#JCB_&*4M=>>MyP0!#r0=}!it@P)R67ws8+k{=nc$;-ByJs433 z6q@SrqrnG)JiY*;&QY@UjwbLM4Q~FJh*#_(tYIF~=9n_$F&_sUvzC;8#=H=S@^QdV z%wc}hOlo%ock^_xcalEdI!HetZsh()kJI?%G(h+A%1T<@q3_$BG~QySZ% @IZD!orMP1BgxmqLg*+1#kJgioX%&3qMm7xUI8#T0Cr~ z;WN19{{h!LT~8qD-<9D~zfJbz0|Wc%%V|13JjPe)SsL;4h@ZW1x#xM6Dh^Z}_)2j= zZH{8JO1~fn-u^!nkNNp7U;%-9-hG*7tzkM{`ZSH3{nQ$*A~u06vw$rqbO0SRD z;}K2i*smD)GY=k7A7vdsHTyQE zhE-Dm=Z`JLBN}Nj7X vAev5^mILHTfkK4}pokJN?&L`UZUQ8b_ 4(fEes-gQsc6NoZC$#5eZ U?d z_P_k&l(H?ruc^tZnTi7y2Lz=4WN1|J;}_z<+y9^PU)k&*14RGyQF^-bzofz1^E6sG zOv8oO2(C7~F8M9jGv|@J7w1-|aCfP@*=EUVWjifwy_dS%AEf5`gEZ@GA)Z^I5mK{N z0|lx86OhD Y3_r?0*492)a3cDrJWCmTQ1cdW-U}K-*Z=Orl`Zi zT!3Rc ~!_IW?Gb>yT!En;n@6qyd5P4&|ajz#otTU zf?a>E+=bz{c^v$p28SSaj^Qb9>8Fg}I1P$l5B> FY^6JH$Ed{n5~0@5Ay-@Lvbexqh6_f;$ENuB;a!hb5g!Mh!T-=U3QGBDF`#nJ zaYUaO;7ir|9Dq0n_{A58&;6mUQe&t|K;{KNoI#aBLBD)%H#=!#{YI)iY@{3OH~C1I zrA0mv)>hY2Z*_&G`UQYI+H_IA{Q*Qy9AEh3Uy5`I`kgy5MjX}RYlExyT+QtWKDk7H z4k#TAMrp`W{e=0TS%Y&YKGGQbV!~$Hp})!BSPQLd2W|cW^J4*f)h@Zsd~yAv0e}2U z$ny{KNaehX3#zw|7krd?=4+g;Cn$C7Z ;rxs>7UI132+p{V}3Ai z=3$j84pbcYs&SwcnqRek{o4BT_Wz;m+Bf?iOV*Ee)86JkOa1MS(wwE+`m6;oQ(VJw zkwZQ!j)EG+JHi)1E;d1>nCgpbskMG9bvN&&_S&5^?*T#^OCe-k<_=*mn6VarMMj7N zECb&FNaC4oauRZqUuv@gG$HV{eao7{{5-G=WuO>3sfQbuwOnXUIR@b5ne~JNNR&nU zM0*7_(U$$OO 2#dXb&m`TNBz6FxhVAqx|9}`XiiEI~g{jl$}D1qseK|OI6I7 zoHCa@_k+WJXRxMLJe-M&`BoG!85!+lvjpB#%c&YrrrA0)MZMHDk1qyWq#VD)9@VAm zFrQF6S^_q}D-%XgZ2#p_v)N8d%i3Trrtu~~lzQ8Mzit-*in#@qMQM59IK(n|@Gsye zycLAfvU~z?I!+_t$N;c;jy-7D3j>rjV{oZn(}wX_`lVYEc%L@H)-yW9_;9TmhfYf2 z+=lIOo7{ Qa4`Dh^Z}s5nq@;4Kb(-v6O)AI<-vGuH4XtQn8ntlJ~Ynv*4fga6Uy6k4hR zAY}PSA%q;F7Ns6SxU-yE7}RyQ?x)tqom5){gf ?0I*;|ZK$|ft&(-cGO$N# zupa5V0990)Yvg$VJdcQa8;O)pB%7)OYz3sH@mvdUTiANc&>{^wTnR)2#CYv}uFcjM z?F+B~L#5VDfTBiCP+cZෟ>d1F9oq)fBM%$y CS0forhu4gYPFypxv lNd|zVM753wIb@)W>*`^&@cn&Y(C&;W(o6B zux;gnJ^^bpEp(Z;@ m9IxP;eU5JNdT_?NY13rY4L%xlUW;f3Ml>k0pww|_(8u5lMEG84l8g7F zl3Y{N?Yx%l!PMNuWsz%mcKv|p=P^ml$vjaRj!&2@{=8D}{Jp>a@xTB3DOI)r@BBbk z9jG{PojDNypYp#bh^;Z}VnV4`FoI14_Y?kWjYkOa=@em2$eZTkHuj L96wQ}FwvzDm5NR8(#%7i}+O=-Wb4L`M=pVF3uB1bm1o;|Jl7u#c5)UKTJ! zy&-XFfPc9iz=G|N1BeB3u+pg6U!+_>jn<6*_((fT!Alg&cf4z15=g;w+ZDKEGUG}4 z%UfpOux)`yAXE;ad8DoE>77BRNWrD#u)hTq)c{exQaS;}ieEI_h(6oz0E?6{*-lVr zqon9_KE1rpGi?TaPd2gI9X%;tDN5&q_kwPINk>t8oaJBADu|Qwxvz3AmcRjiE?(M3 zI4Z>pTzG?2u3q}_P{VPlfz77N^#QDTZm9sJ0#mL8zk*?bSAcjuxGdxJ0<~FIr=ccV zeL jAXLF6*$CA0dEN;eFri!*p@346=cgN z=Z-ll0f-9FrvT0o!1N3a=&24%Xh*FpG~*1Q;5ARZq7KP|UV6!q%r~Lt8agg5gtJmN zbuk%GGpYu?)FjI p#5Ynis!?_pS#kbGDz3`|YrrCzK%u@1dQc@f;k=H-A0yQR5%5Tx%(;4{px?q| z-lc@vE08f#J`z1dGOK>l_;QMS& _RD#1wk zr6?Kgb6@09s(?KYlqq5XS%s$(eNu&2L+zzXPbeISk}{SJgkrs*lqot#`w}^~7&HZ4 z1tV1DMS|w&3m0<5yBC?0C`KRTN=ABDRHRW*w8t8@hKb|`C{64Zo=x1>YX|5R2oQ*r z$AQ>bs 4kQMlI=0lk6)`;^@reUd)%wAIDR;KAGWJMAuwf*YjwC%F~op zq%6xikEqNcv7A9 y3KbnR_!iyV|`vU+G37`R~qdz3>SSUE+jQlIcL2u8g;(Q*LNkoGeGoRVQ58X z#es?g6$jo04j|VMYzj!vemp5G74jMeHhL?mvw0g3`Y<)NAEfEZ%{0N_F5stXB9hf) z*v9Xu96?-Et02znlI5M^!5atQNjw&&NSDGlAEnVc^+GWPc#Cs{tp;>}j98lv34htH zl?0eV(z&v%fnT{Eu5n(2ccsf_ +H}(z&nkE-#i~C@;pk-Ydv? z6Nm~pgh8s<1fhZ|Q>g~L;EeUz9_?%FY4(G_6k`?F1wBD@Jc_kksk+She*C8L=pz?p zJNYQ51$F>W=&Pf4jL!;yl%Q-5k8=E_Osj^Mekf> fhI3zAc_YPbqP(KZ{CX? z0{k+tA=|Yc-qB-8 &` z4X-2KkMgC8i)zAP^FlCEUjZO8*AVU^fQy8rzqq7b+IO8*;Ak=`yjoGch2omR)@RbD zD+_+%i*)A{#)$}jeT7iuQ9gU&D6MCN67coN6c5^{J2YAdck75;mf=|#4N8~1(l{a7 zr(!{h<+-2LdTNy~L1}of@Z9$Vc>ziV5EL(74WMF+8e$5VB71GUR!+(wSw2&S`mNU# zYspq7T>^BEUSDMT#ko093%~RE ?<6H_xk;+gTK7=9Xry9MY}3p{n(Ew!t~n8bMVUX-P{<8l#r72qE` zCJ=G9K>*SAQY-ZUqzm+4J_TRY0?VJsl;eG~JvTYeV&2e3naaQ8d|i|*UnmP*(_;ln zuj#;4WK|rfI8brm*Uy1V!DicYEcR+>w|ZMQ2`qXy)i-Yu4{AA`0a}pDAsEB#F(N+# z4iJ3ha_HN%zbPmY(icKBw<+9=Gw-Y63W3kP0HPUKi9w7F6bdSen*ZH za%-74wlQPrJ+?X;u_X|o>v)jTkoZey?Rpw60@T+CMmt_i^99_@8IV)<)9jy~vahBZ zP$T=FrIVu^*+0iL0;~~ObBLx;z-k*O8jbQ}kLoN(cL1X85{Lq{IsjC+pjwGNIF|{+ z+Ku3>p_K)Yxo4`o6=>cNd ^4vKhv2KtMV9E7*t=5@E(q0-xTuC<1Be1b1*6tXV?N6@TIj2jDj@pR8Oy3C6$dH~ zR2=xp98icO>}Ci;w^mY+;wQtBYv`OpV5 =r+(0 zQC?w-v~=sH5WrR@daR)t;!f61l_1F?icuj6$)W;A-pN{{EMz5*N6~&1ym$wJj0a3? z(ImhF7-*|E;bj4Fm=f@EXo>)x0dlD*12pQR9b1mrIT)a-`8yxDHzx6X76duirc!=J zSaW+Xb}jHPb ttgvwY%(B%5x+8>lwu`a!#F$nIL-( zeS={JoO#bsX(|9D pnv78hwBB_s{;flqy?*cWvA% zdVjMxfFKhXx=-hfJl9P+6lIEGV>E>e4d4mQr$7p=Xl)H3dh6?{PL%uFBHNM>n@D$U zorDy=3dgC4$b^Ozu}&L+07PWiJaW4fu7Vn5XU>#VSYM{7t+>NE&4 }bz z`Lqyjb>&b ziU7xPo`F))mC)u1N^CNNzj&2j++`r85(3~6S~oO_YTs(|2B3MyviV?emJSaN(%#;F z+TGntuV3%Q@!<7t>L0vLgVQ74AETY*qhpEP4OV+;gckFFJ{d677*7+H;Rh_gpAU%Y zPO#c@wh4-DhFG>&<817t97vTdodlF<{1)5*mF=(8@^zr8XZ#{n-0*r3TND8bCj;zH z&(iVHemX9|J17p|NgYOg4;xcJDNFu!>NGc9*2d;iVA{bR)x5|DM!W5(xCF0R0d1TU zXcs$HgMZ3f?PEQLNdll$ha>s#Jd=kr-Q3CYu7&2b$r65-%tm7bCC!ohvmLM+R6r?z z5XZL2m)MBE3uj|cK>un0W ^lqtm+B{UaW&601?7S zMFUZ0ajCE_I}qZ&ya*8*;IfdnQXr@@`F07;)cch53NVZ_)P#m8!vpOrM`$7==qPO~ z%oY3svO)pNvs_Niq(ZNO8f%PKy$&aOWvh7=j0zMf$$Rvv$Tk$3DEUXfy)O`qMEk*0 z@0$gsyb$(?G^$oGd*54$V9X_FfC<_5ti|_Dp%A4G`K2fQ*p5a0YVCyh)K59z$+m-P zLIv48;bq|uh>?1884wnZM1AZxj{u;1>D4RtjCuAn?Y?}O_5h*BM@MKn`vE{F=O<_q z2eD^oZ4ux%SwP#jkfs2}IhsKMsC!$wB<*syfO%Z&07L=xI)(w-OfIR<1z!TtrKPm7 z)Jx0muSrDtHk!>ITG1t*`$3= =~fZdKt{%S;Sz%dbQ5> zUjan1FKqxy8ys5z(S^k>?JTf`(ozHwb>Ga;cJj_ScCBY kKla{~*G2*GV?=&4 zV;EEC89xodDXL%jF&U**_}K+aFLLalJr6gpVxIXiH>LvLo$?_fD6LV(zl|Al$uSm8 zJLUq>4#zfNTqmWDCJXSZ!%9Wij}~>xN2gc$vEg;T5hrmOzo45}Vm^3`>FeK8#`yWc zW$9~uRsqp#Jv m%}G(cz?tMrWb&JpA+T1OyE0mU4F4Ri{@sL-u}h5|lPv37Y^ld>{A$^jX% z(KbR{sTqPdD7ji%peD^8X@?U*p+Yx2uX!(?(}r6EX`d-Lt|8n5kO@Yq&MXiNy3`i3 zQ+cg$I2ocHt)m(30Ftusm!7=D9`7mYr4e*+QJ44B`dV+aErcoB@g7N< 4|dkl&dv@XksT8llQzrrJ%K17 z%_Vv_d=ITUKwBVsaCnsV$OqV<9vz*8XZ~P_833lI!!dA$V4SsBs>gm6?K~(ifN2-a zsDSs3eLQ=Z6{z+0qr>MyWF3_3OE8l=YC|I`J#G5o;75yNpPlv20Psg?a( E$O-&zY-?{GiEMlrMBixjlV_Q6 ^R4{A1wLr!%5|wE2fJ@zY?heqF;$&{7vh`_V4}nf00sU3-FsZ z?p1%kbPkA?_@~GevMKli-moF|w2i~c;$~{I=VzTzPV Abg?&JdhBa=7KpIbdm| zjU#U>=R+$w4qa)0#U{3UAxu?Gk^%&CjC&jd)CkVdEO8)bVH|>(Qfhik`I?iE!2T-g zEh?g9l=V_zJyJUb7|0GKY77M#Mc*hZIU(F_lePW^Q2@p)!w!d-7jQ3PZMu9cr4$wz zM#Oh25jf>sP@(3Fdxr9v0EPuQrflzMoA8DA!chvIX%1ldu;=9641#DYz%ED1=2)E> zJgFEQPbo*o!mC<4L>U2qoEslgJ67_Hj{)BeK0^1|=|MW(KS&3!U!e{CECA`N7f%D6 z_Ky$nfF}+nK(Y?a@=V?Z(1+=5w1yqDdmY9F9cKV6%Lwjf0ICT9Dz<5&uhTK!^DNi< zG19|Ber0tvt>W;c?Pm*{PD47aZ>*(Tn~Q0EnR+{ZSPat~bU7KL9R%bpGOrTOQL#;v zU7NSl_WA-I>Dy>c2LROLw2KMBtKEb2djC8f9_vJeh8AtDHm;n&a6Y00;sD$;=$fes zh0d07WTAV?hd> &Lh`Yq2A&Tb-;4cI?IUBOcf4Nlqy8}(<9)Qkr)YHn>io3l zXjU;r=${;5PA~}bgWlp|s?$&4Wa`%0T8lO@VnKU~26Zrx54S0%4B+qpqk?w9a%e{} ze-M; n8&(MTTSkfM&1w)yX1_cNeM1g^j z=YS}-no$J0vdkq-s9h|Cq7s!95RX&Ao#$Y)eD2aF*8&8O%HnVo5k&B=WlgzEA&ARs zj;wkDs*K5q7L2-FHWeTTu;X4PBf~BO<-4@1M#@;Df=#umIDd!Mat3fHwXP9HO8y8E zF+YfU1db+-_R~0(E+?DSytX@lA r1TX?R%)D=Qc~@{O%Yt5bEI(~5 z><8l=K_QF>B#qI0j)!M>h4<4`Z*{bHuqm{zQnvpT@cHQ{=^6Re%V*ezzCz2mmj-7i z*xB;wpcXR*%{KCwNSrjZ;kBAQV~C;%44~>9k({6xV5e4h0vI;1{T%J+@?taH+F4IK zw{E44O+H`%p=yNb7=R1%h9~K04?3w|4W;y|9bH|)OMj02F-*~sNPt^MYrTXPbz@@{ zrRFC0w*jM@>BX!4^z8Y5`s~Fa&Q@qlwK1h_%@Yi%G^5Tb0CfaFoWY-wU=uoL06Z0{ zEkIuv5B(0=&{6_r$4{ 1X8hgr|0Tb155(& zcnlng6o88}HHu2iSeB) G1C2ER z3;}4+j12+C0y+VPHLHmf{$|LFK>{FD2a@oT$7V3%W}>b09qsz8uiQ{w?U~w5YYNWU z2WX>qG^(@(FcOFc2;qI}5RByw=c9S?7Qk2VONP!e)@0Zy(w)3tC_D~&)o^OUAiL0z z0 4Te^>u7RPlKnYr~N1+ zK-{{yoo>zV0%~snRu?1R*xE`vHxJXz&vw&i&t9Zmq5vEcPU;j}(=(j0G%rb0G^6tc zz#oC OXV1Kq}o> !nvc*XpJ7Ye2IzLzus_8{ zy6e2c?)K#1kmvgW{M+1{X=1?m*BK~7n;DhDS>GkM8UH3c^KYhw_7=Y_Y(oK}XhG|a z70dQHv= Yc_2OT_0D_elS5aw5n{`xo&0xX1>Vw9wC29ze^h+-_4rc0Y?(q2o0`U1<}2-hIZ zrS;H5QXT;tUcx{^Wu>Z40F_Wp>Bxd?QLh44=)-O6;8_k$!#Thq#H>;`|BJdxt)x|k zGm2U#KpGTA`KX8T3hFQch)S}yF>jm>K&5V%Zp#$yBk2W`Q4@8lt(s2J2MV+baH$9O z6s?tEg)%6NhJb!0D9tq3w&2s E~1cxiL)(yIX24an7qxnwLKr9=#> zR#f2U(f-g?@;r3_q+?@%o*ZNENhqe>m+9#B%XEsibBMMRR2mw(1?pVTAqH@|FgZ_m zSFq3ACb&GB-hKLeOdHx>@&Z~`dLPTe!hk%6I-b=-yO;SL9|BP4Sc;cQz@9zwv7N*u zW09~#4 wchN8boOs9OOqWs3z&vZA z4nV24kGvnZL>ht@wQZcaROut_@Js 1Zgr*r>>ah(#qlniotsDGa zEndJ{-W4R}vep9#hMs`J0p`?}0u*@U5~ntno`p6{Eo<}wYgwF6wCS6$oEp390J^pD z^tp~UK{<7JFYG_55Znr}07n3ap5TJm=nCjT&9B%*Ev?QjZa-RsjwYa2FlwkH9bYmZ zDQmreP=Tn8xkYAZfTiPXFP$Ckr$cQfU!oQKOb4Ww0lp?^1%X(YTQ<`WAUYuTI?Z%{ zYbD*ewU*xBUQD~UR?>^z(%uq~b$F7_)dWMAK&Z)*brYv0mzP_3kb`9jjYO=^!t=e^ z>;%S&WpwDvd#+Ci(B4V6ZttY8ee1(?=ix)xI>#K~Abs}yMSA|?c{&8N4YAvFq?!P| zT8m8++Dicf7XV@%!Wnhd64HLHK0+hQoC2`QgT15EbbS6eJtYR}I)HO)YdhV)cRM|} ze=FU-wUs{n`n|NV)&mHm;hmlmvWX@2DL(!1y~%{oj3hL{jG4>lE$lesLy7vG3!_1U zC;@;*Y(K|cw8jEa=I0qZP95tsb 39wF3h&6VP cRb#tw^Mjoz f;m{TR=}r&k0_ zJq0Na2B*}evKjR-?bm5%2GZ8xSGDyp+Co*znAA|mj |Up^tw&$FtLv$?v?{asTBAPZo%_?yX&bYRbjpqj$Alj^?$bBo zJasYfo#Fjt5Kz_p2KY5QNBx`dFVHC#*W3#vN;zi EsUFDgs(tZrqo9+Q=Akql#DHs=gs~V*~L6fS(5rIo}&@pzCYA-#d zY$psz0i3q4+UsgmbJe=iYTv1fGIB%pnC;_DgWLPb{%$&X`bpY*{)8=)UJxMkbviyg zNHe^b8obm6FfU< PS;^h&e*r;jr|*RU`(B!NjlCwLsgn;t<#Z{50?G#cGxUHzDCom7o}`sA~SqOTF} z3ZQLceJj+P+c$5e_4N(b<%z!pDDCRO10c1pP6l}`aM$qk3@@U6Vo)8UrqsCf fX}ag@IkEg|D|ty4fH=sfBd~aNso^|O-C4b8s?$bTaD=b?KaE> zl&Ypa=YwO;n)@6TF@qSJ&byvJrLS{B2}C#suKnQZqJC}nfJt~Vod9}|jP#EY^}Myj zo~Enp<%tItp(n 8BMi9=JW%m=K`9|A^?&PEux5@tegE&wTnGS4wG -#EZo* zYxPY5WVp ~&cDIV;dx>oTx5?p zRG^@#001qZaM||_hS@?(IL0`@{Vm4;mT?C!A=+=k2SKYqG_;>+F9nPS%QT0UmOcb0 z_!Wv+w25Bp+MP9zc&-3e1snD!15pZao&ktFaGiI6aUxqIJ$o8JbpNv_7>mAQ9T|@# z0&jL*lV4g)o5WGNfeZVMjg7QUT%{$zsC!MG9zFpuvS~bJYXHa-K$IR?ivYom8(XY} zvlSB>ytAQvvq}44p9QG$g|+jEK#}JdlG+QS(VtO|yjuX!-n_X57~PIF`zN110f6qJ z)jR;WPSXv5=fel@r+fF`!_EFq+P<*^AjY7R^?yBwY%;)CX!EcU5yg`{1{l4A#uHGg zrt}aa&X+G L|T>_E~z4A+3t) zMLwjObK^0g&1H^gi=sj27$B-KZ=G}0|8SfBGDqj}!J;Odu|h?R(vv?40-!Pv+*7na zg3boE2CVBhI_rS=rPLp4Q^7|Fyc`=601yh 96%hRmp8!?&D-Ki~_)Xyes7JvIV9+2_V5Q+F5;cHm3AVy`4XLTy zxdKy9pbWEwmx SQNpe9HvzyY)suHhm2qu-b(zyrZzhmFHE z098wu1Bc2d>H}of0FiFhRG(5Ft)i~@8ebYcU5#c9qg&h5xDXHu&xTCMGEYl{ML5v?qxb*k&9@4enJuNp_lK m~cQHy@glKzl+VcaJ7DpfPRNFY|XT#BuyWGeN=p1go%rfc-s4=GdpmB0hJ zB`=&$nwprh(K9Fh30Tb=*^7LyeC|8%LaKo1yD&->jTHxeK@NQ9-~9(aNU5>~_yyVb zm46Mng}?*ag#ZIU0R|@I8uoS(>&fMM9 qdJX$rEx;P>EpA%ii%~&|oFf zVxMflW&Vi41aJ^1Nk H&nAVVSK3hmOwZJSp$)UI z-C72yMxw6)uz-kQeEEcl1MkYq7VkG%7S`|~G^)HQ?$h>@^>?DG Td$JDh8 zC_U^0xY=~RH;=eTYIDQgA3!a5m$P-WmJl64dca EtrQdu~UI}`DYv~ z%V|F;&$|Hn1;A-f@ZDQZAET`{*45+3Pca?A%MLo$Hn-D*4?axK@qT)VIYXbNbweQV z=|BuDfgo$;*ulDlZ$IaFt{I h1|m@(4|I8OzG;sYdXy320wkT1jgg+w1^v6OA^@`~H0a?$w6YFsE?b z{MeILXMH|+&M9*?TS>?b?v+dM9N`*2Qs-@+nz zPtwUNmgFD*ARRvXVLE&9ETXTs0Y|HV&|5pV0^~h-?> NPnId zvDI`dpgv{>XTxWJPg@y4>l`<4f`DSjm`w|G0ViW0sdiZS5`ky6m!)qJs8z keh{yMRZ*T{w}&01JBa_+Q#J z`r*M?NPCPa0~ZM<)3h7AFJJ>($9B0%8=ZEKz@5$X>Bo=KDPZ(Rk3L14xddMxrtN$8 z)7`JVN`Lmr$LSP@uaOQ-0DQr83m_^jYC-1!QBWh{9@tI_V@{xI#A9McLBkku$%gjq zemhWu%N&`qE!32GFI-d$uL*}*=qC2XhG}x2)5(~Cuz=AaT2URL80NITu!XY~fl_Y+ z%5UBSh^_-Z3Fpd340ZxQ;%u85e>Jcr@M+Qa%q3^LiSj0H%0GFR?M)ds9)*Th+MVN; zA AsRBlq|4qzw3?a*2oOc1 zYMIn 5sV6g zXD%JvLkp-4Q&~tj)*+zjd>>EuPtb${LQkK4f=f1ACIMKMSJu;=otuEI_tV$OHvpjv zEd8oE6p3U|2Z*E}_QfrXTpq4tLwSx#!gz{?k9LPRJRK1?$vrmhdo1@-g<9Jg{mk04 zJYqW7_z~iGOtB}O>ya~ODVuti(T1);)9Ug%T1COw0`yGS2XrHC6A*N5bBm>E_LBtw zjva$QSaOyh=MlqH155_+g(uo2gY78BvO9ESGlt+2OfoU&cuzBjZM3dEme|!WKYIKK zr>4F1=O2HPHg~qu5 R07&<6d^$clOp`t^)ADG9)!NcpObPc`o#WUQL3MFP zniIoph8ER*MO_sLS^?*=l+Ii3_MoGe0cia&u@4=twZj!x#?A!8K0x#&oX)y{<254t z-@W%Bz4!jt)8_Uq>Q=KFGdK8{$IbcR{D{A e0;2E2C{;989JtOL`2BzQFaNcaDqDc-JVrl-Ht|9%7XuQ)zK|u~ zHo1kP%v{YDQt&4VwKwJAmDaxS!Id(fcX|P1-*_kt&7v9MP1OOGmCO+5qBrm&3vR$x z*o^{)44ou+w9ExHfSW*qln0(*2deNU2hasD6a|G)Vb5u~-~m8VfEDiv*5M0+U;9yQ zN8JHnjuuUzr@duFmInk$qA7xqasj*p!2oK|wi#9m#UEQG5twrSb$b2eNqR=!-`gjM zCSKn*cR_doG`Oj=j~Yi|jBSOM*n7b8E`dN@+8&~*JHi3z^yDOH?cr%J*gL}+sfG4$ zhL`yq?Ot9U*IqOSO|@17qK3_AFvHQmBtn2>TA;p79H_Lj)K*i?;{r}f^31H}JQ&Y! zc_DZmqd`1FD>)+1(Hskg1&nHUO{KQIJeO7RfkLC9VRf QCeGrtQ z!E9k~+9n%OAN@P;2t55rfjZi(qxF{FJO`wKj}x?_M*0^(Z?dJ-{r4YYI`A;|OEswL zIb~#N-iiqbMm_NnQ}jK9@q)oJ;f?fp_pjb#a>1KCR2;89dZV7}dr^VX>pM0TWfcc1 z4pbcYayU>3r!4RR2YOB;v48{tI-7z}v~KR9sI$vdZBi`X3feLl34Fn?5}J7QDjy3u zSP1AW7jvT#C$Z>-_pc_wMp UD}WY_O$_S -?)=?+ME!=sZY43eL^?spmW9^nG>V5Q=ghy0nQ ;i_igMz*U=#E?Ce0_3N#7k9Ya4196f2s*YObmFC1&jE#pMB zxw#Jg> nwh;im`o%*;7A+{M5R<~5&a8lnk4X?rRkT~RPqZB5$C{ZUNdu zgUXDA%TbR#e-b_;$BfY= +r%4_O{O$?bJm#fT18@TqV z0;1P`h$;dr4pbbdIPfKM00EY_3KEENjz&v?* $aqka}Av!cl-LY!EyMNW3ZdFutVx5G<*UG`nms z2(^x&iT8jyy3O!hO(t#glJPDLZts4UM+dI~p#+R)?@t|LW`H>$B4M7+iK*ES5Ncp} zm;BWvs!_G=0pXU^3YyepyI u>oG>p?J;BRZ=etP)eVF23`XjGFbO~Di9kHB;W z=yW;#(WA%dqaXb!0P+y+XqUZ2Z{djb?QefOJ$UdSY+~h^Kv^J~KbXp~v2}UxHJiWV zl`a@P!;W@B-y u`{09glfHE^S1=~) z7#eiS1Jg&E@SeO0%{i>6iDI7m*c-MLza{)4l|0Eeq$~3z3dK0(v2wnaz&6kAiz=?| zNd-i&?a)+&RUD`|aLIwc)BohZOR2I2xa7z$dxjVbVW!jzeV;aRhTvg8$Qr;!&kSRZ zBI62BMvEDpMbpa2EHF7 #VovM3!au)A EQ%V{p_u89M=FOfVD~NB!s zg`B8EUGHBh7N^ot_gnly}%u^9)cL%l`HZpd3Ah*3gjR;M1BCWr1uU`zhef zApft>yngifQQBrH`WBkaotrzslb3t1@jN$fDPffW>mB-SaQl xRltuAO4JTDURY6OUH!P6;iXI|)t z)TFKjz&(9}opn6n!x4_Tpv|pXRP9$A&0(qu&H?-GGBuqIi2$baSuaglTDKmx>V{Wx zKE(XwL=zBA8?y7#d3;DLEcMc@`*+i~{>ooYAAIARX?^ns NizZZBfuA^ z)^Mh>f1+K@7~TYrUKgC83zy)tIQLQU-1!)PUeXowmw8MZv0K;$-9=s3_)vk;Ydkm= zX%z=54pbcY@;M;rP=F!L5XeY!5Dx+1(J0LTp~^V3rA&p)%NK84S>kHRw@a5b6tDi= z2kMT-3ks~RR53+UXovuiE_dga0y-kw(R``B;wWfl(Hrn$RoGh!IIULX%Ck2CfXkb_ z8zt4y!6Q@Dqy1;D-+BcRvD7MoL0-NW4f+Z>04hMk^?L)!8vCshjU^%{LY=*T;m`_xgoZR18gP*h#rrRk651HMGN@| zu;(sC03<-6yBBHycn vI#gv1FPcQ=gBo+Ol0aAcOf|9Y zjPx;%L#r(PZ>(;lZ+_z&X&pOF%{xv3bz=Zsm@?Q^=saN={n^t`)1!}mgdOMObd2dh zpIwP$kR}L%(FYG6#FD>ur~y6$Kmqardl6y^p26~ z`*Gk%X^zk$&Z>aY7_xKP6Nom|E^{;*L3UCDxM{MWR+={*mkBXN{qwL (W%zEP;NEHx$2L`DkvEo3*fr adIIn^GW%hKtP~a%4wynCA?Q2 zMR&C;KvWG@2?q6AkFr!W18HS@RJB_=0OdNYsMLDO7lEovsuRlSkmD{*mI>e~KL92T z+HhOXaMBT0N)P4L*M?0Y9k37Ku})dTCJBrLG-^ESfZaM^YCdMqa=ft3^U*n)x^~)H z-NezR70dFkj&{?Xy8typIo-n{XLWTYfZ_ aZ^0{_+1wle zPzqRkjdRsUj~=HLG_3OB-u-** hpbOavG>fuQ`ew*SHx fIg&qfNf@{JJrgmg;tSC<4ws$#cZ`U-2ctmx{DYhfU=9ll#TZH&UQd8Q~v5 z)W*TfICsvIsmp8t*EsiHS@w fA6i #A-~6#IShOf{;u0Br!fI|CSEK(J7{o(nRh#Pwu>MKoxm5(86QvyKa!1{-SlC@pi; zaue3(PY++G!@ZYyFdc+@_U6_ao-ntGU38Pz^a>iVwUNf6>tX0PWL?C&!F&9 zLZzuYy~de`*Z{!9Q1=R6-N61HTQ4o5# U3V!HpYR0j9Z`o&sRqLvw9?ll?=# zp1$?1Zv`MV##5}#tM2A~0cK_-tTQ$gAXHH6{N-^xS2a3i=KyIsqW>>nyaJ30MEhZz zaEe+Oi% xtye^~zzPu?ck;Ovd!1>B zXEYqzAxnWff+p@6$tuGQfB=FzoOQUP1{Bl~{hYZ^BxMC+S*wT^ZH%`OMHT>UZ30|^ zP@=3+^zFK3)gVrdqHkTK0IMA39aTf3W!bFUctKo`0c~e&qJDq|Z}+oj>Ev)9N0%B~ z_N=58@)CP|Hqpj$i%9dt+X4s*!UAv}9;H1zh1CANV#D?m*4{Oi6pWch8j-pkkQzOH zG;EE%KZ}5 Pn(23Aou_<_~8Bb(=r>%`=Z)Q1Cc&_@E~nsSo-k2d$`oUN&}d(%vMhCVT17S z;ls3oXO`eo!%vfAVDf`Pt*Sv&!xca&NB@+1?Hu#!Yj1Gu~v^ktbL&Sd{OZW zAnG|w^$dvP KyK9A&yHWvVBX!Daq&?*)2!AAcKy$}Y~V>h=aP87Ur$Uo-Hfc5x3 z9|vk>Cu94JcNFzRXoO z-5~xaym{RoRY3H*jYvgL#es?gUsVqLAHVb0{w$?yV+$Z?L*OczLnxvVV#(6jPOM#u zOvp$zq^6n~<(uGC0nNdGkvu9;BgezyKKHCxjpN1b0%YV8Z~l(@is!k!ZIOA9ulXH? zxaMZAm3#gx?}PLNdl_ojueiw9oQFmdZ5 F+VgAZDY shk`rzSv>Gl2r0Z3Uc2cR!61Hf6Lmp}1w z0Ikws3N1Gvs~kzlV`wyr)i9JLc-lE;Z_tDN!|>pG{`>`C9iC!DDoB?mt8&R&t+#VH zs?OD09f{uo7HzN?d*(h6H0H^L;dJpLoMgNK&J9c)0HbbrZ`POT6hPj`JV5Peucwxk zaYqwsEGQecU*Y*Cg1pF50A+q07G-jO9TVyM@l?)vp9EPP9Y?E-KWVG?p})%P^)*iw zD81$bRFPM4pyEKqfiI5(ieQ8;@or+v8DiMfBFHG((a?-$p{X5U2yaSrCpWL$euEIM zzDQtF?(Ii${q{}kEAAmfLjcFIIJd>}6=6yKDPNHq?;wQ9Z>JE@Na(O16_}X0w#Eh$ zy@e#tv7lV$q$Yw*=B3XJ)CE08NjC;%AK=sjn4zeIBzPlW5ee{O1P4V^Cn1!!KxDy$ z07K6wH%d3A(?mPQ{&6}bmeV=z<^z`N=eXA!fOBbeIW1sQ*-}%Dc3K-p!A&3Fss_-d z=zZ)V)sE&ZhIFYHTxuH$P(@REK2l4@h`9t06#+!iFuJXi%k^M8>XidLg)Wo!kTsA~ z%{`$=WBSx*xxWUeTcXV_{a%EwCeOQQJJonj1;2pcW5AZ)O=r+>g4fb9Hn2AUqU-G8 zxk?mx<5Behu_qq29RO1WY*~lHY^D&M@fUp-RO*!GdGLi_5#uY6opat#4EVxx z3zgx_f?vL5_Fs%QCzuB~llWFalRD)iVV|I}` K=gW#PeonD zfr ci}F73U-?E+Yf&yc6J0(nOBJt&U@Zl&&$6J+pwTL$eFZS| z$2 qhjtY==XVYA{@#rl8v?&QOsGx&$@?&e7-;jVSwlp6uaDe@q)jTxV}km*W92 zEw=z-oz-BPXE-z+9 v^mNFMCngsp+{!t15kEtW_hFOW0y*NsOK+UqH!ID-Rcs7G|g%S zT_Qh1D|%|IC_w3n+bluDKEQRIrF#MB#>QGWCJk6NAL7D)V`~eID*e<+37#6&-(`3Q zPLQVU<%IEYT(!Z~epK7nKHygE=kamYc*={*d Liqh zLU8XIwlge1XUqf#h_)G1r$=a%nLio1`4QoK&AI%oZD{^z@xh!in5N@>G}JGirlVKS z(+xoP!qO_S($E|eWK4~9gl(`LoVbLrb7+hYBuNtl2N3l_!ZT>~%1;H9x^xAKi!y3a z9l<=kGtf0gmGv?*xbx?aE !QibuA3PKA6>fop_|FKjM60bxUdU(J^69l4; zP;ly!v^IAmz?a%kL1^~ScbOjTodA_*ZI`dxELj6!G;Qd(KP1?Wh3{xzs30hfn!|vv zpa&X^Os|LeXw(P990Ae}sPim!04WXPJJkWBW5BtAK_{nZ8v$B}2QSj@9{Yu&byFi~ zkWrnK^t5-wcbBV=iQ}YAsarPbcr ? zi Y2+Fy(z7bnPsrgf@DmZnV)x B*THW(V{s zoSV3g?=V2KpGa5J)wVppnxi+|U ?bTGjbw4$3+)HVV?P3T?QwPM%0BfO{5?;*+Nuwk* ztWmt3g`l@`3Xxb|gz(N_F-}Wa9zxSXS!{cDS%X)XiTXq(7pZ)sI3jT0s=2t%FJzm; zH;Y_>wEzMk7~&j6oj0b>Ps5wuDg?6v;R4s%J6BL`bxhkvGS?H_CD&Mf2h6yvES%6j zu>?^*E5kpPJy2VxZK+%Rlv^jc{H&(11z6E3>J+W#s{!<#P114Lg+5Jt>=)Vx1ZwMP z5}XO(wEI-Mcnl~zK`S_9!*%UA1=ZTZf*#Wd&8tB()sXse(XlfDqL~BjMVzu$0G}&- zm@K6lTX3}im_Tb_44~ZpP#?RG0#3Cxow5{u6q-Pn?3WhZ5PmtGF7?BFK<%u{=-P{_ zVGOOU%l2qXwQ>FQ(@z7KuCA`dKBa16P4Y^uXqY^}M^+fWrOGco2!)aS^&U0ddh zcP$dfqEvX-bHD6Y{(G~N-X!N=ak%KWx377sfao