From 06d3d731ed078b9c759bdcc6bd4a8bac3ffee964 Mon Sep 17 00:00:00 2001 From: Ming Date: Mon, 25 Apr 2022 17:48:38 +0800 Subject: [PATCH] Refactor restic repository Signed-off-by: Ming --- changelogs/unreleased/4859-qiuming-best | 1 + .../bases/velero.io_resticrepositories.yaml | 11 +- config/crd/v1/bases/velero.io_schedules.yaml | 4 - config/crd/v1/crds/crds.go | 4 +- config/rbac/role.yaml | 20 ++ ...pository.go => restic_repository_types.go} | 13 +- pkg/apis/velero/v1/schedule_types.go | 1 - pkg/cmd/server/server.go | 21 +- .../restic_repository_controller.go | 236 +++++++----------- .../restic_repository_controller_test.go | 198 +++++++++++++++ pkg/restic/mocks/repository_manager.go | 147 +++++++++++ 11 files changed, 482 insertions(+), 174 deletions(-) create mode 100644 changelogs/unreleased/4859-qiuming-best rename pkg/apis/velero/v1/{restic_repository.go => restic_repository_types.go} (78%) create mode 100644 pkg/controller/restic_repository_controller_test.go create mode 100644 pkg/restic/mocks/repository_manager.go diff --git a/changelogs/unreleased/4859-qiuming-best b/changelogs/unreleased/4859-qiuming-best new file mode 100644 index 000000000..f92fc7fa0 --- /dev/null +++ b/changelogs/unreleased/4859-qiuming-best @@ -0,0 +1 @@ +Convert Restic Repository resource/controller to the Kubebuilder framework diff --git a/config/crd/v1/bases/velero.io_resticrepositories.yaml b/config/crd/v1/bases/velero.io_resticrepositories.yaml index 65ff08eb3..27c97c7fb 100644 --- a/config/crd/v1/bases/velero.io_resticrepositories.yaml +++ b/config/crd/v1/bases/velero.io_resticrepositories.yaml @@ -16,9 +16,16 @@ spec: singular: resticrepository scope: Namespaced versions: - - name: v1 + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 schema: openAPIV3Schema: + description: TODO(2.0) After converting all resources to use the runtime-controller + client, the genclient and k8s:deepcopy markers will no longer be needed + and should be removed. properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation @@ -81,6 +88,8 @@ spec: type: object served: true storage: true + subresources: + status: {} status: acceptedNames: kind: "" diff --git a/config/crd/v1/bases/velero.io_schedules.yaml b/config/crd/v1/bases/velero.io_schedules.yaml index 9fe76d7b5..b090c08c0 100644 --- a/config/crd/v1/bases/velero.io_schedules.yaml +++ b/config/crd/v1/bases/velero.io_schedules.yaml @@ -17,10 +17,6 @@ spec: scope: Namespaced versions: - additionalPrinterColumns: - - description: Name of the schedule - jsonPath: .metadata.name - name: Name - type: string - description: Status of the schedule jsonPath: .status.phase name: Status diff --git a/config/crd/v1/crds/crds.go b/config/crd/v1/crds/crds.go index 54838c355..325c9a6d3 100644 --- a/config/crd/v1/crds/crds.go +++ b/config/crd/v1/crds/crds.go @@ -35,9 +35,9 @@ var rawCRDs = [][]byte{ []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xb4WM\x8f\xdc6\f\xbd\xfbW\x10\xe9!-\x10{\x12\xf4\xd0bn\xed&\x87\xa0i\x10\xec\xa6{)z\xd0\xc8\x1c[]YREj6ۢ\xff\xbd\xa0dχdz\xbb9T7K\x14\xf5D>>\xd1U]ו\n\xe6\x16#\x19\xef֠\x82\xc1/\x8cN\xbe\xa8\xb9\xfb\x91\x1a\xe3W\xbb7՝q\xed\x1a\xae\x12\xb1\x1f\xae\x91|\x8a\x1a\xdf\xe2\xd68\xc3ƻj@V\xadb\xb5\xae\x00\x94s\x9e\x95L\x93|\x02h\xef8zk1\xd6\x1d\xba\xe6.mp\x93\x8cm1f\xe7\xd3ѻ\xd7\xcd\x0f\xcd\xeb\n@G\xcc\xdb?\x9b\x01\x89\xd5\x10\xd6\xe0\x92\xb5\x15\x80S\x03\xae\xa1\xf5\xf7\xcez\xd5F\xfc+!15;\xb4\x18}c|E\x01\xb5\x1c\xdaE\x9f\xc2\x1a\x0e\ve\xef\b\xa8\\\xe6\xed\xe8溸\xc9+\xd6\x10\xff\xb2\xb4\xfa\xc1\x8c\x16\xc1\xa6\xa8\xec9\x88\xbcH\xc6uɪx\xb6\\\x01\x90\xf6\x01\xd7\xf0Q`\x04\xa5\xb1\xad\x00ƻgX\xf5x\xbbݛ\xe2J\xf78\xa8\x82\x17\xc0\at?}z\u007f\xfb\xfd\xcd\xc94@\x8b\xa4\xa3\t\x9c#8\xc3\f\x86@\xc1\x88\x00\xd8\xefA\x81r\xa0\"\x9b\xad\xd2\f\xdb\xe8\a\xd8(}\x97\xc2\xde+\x80\xdf\xfc\x89\x9a\x81\xd8G\xd5\xe1+\xa0\xa4{P⯘\x82\xf5\x1dl\x8d\xc5f\xbf)D\x1f0\xb2\x99\xa2\\\xc6\x11\xb9\x8efg\xc0_\xca݊\x15\xb4\xc2*$\xe0\x1e\xa7\xf8`;\x86\x03\xfc\x16\xb87\x04\x11CDBWxv\xe2\x18\xc4H\xb9\xf1\x06\r\xdc`\x147@\xbdO\xb6\x152\xee02DԾs\xe6\xef\xbdo\x92\bɡV\xf1D\x87\xc30\x8e1:ea\xa7l\xc2W\xa0\\\v\x83z\x80\x889N\xc9\x1d\xf9\xcb&\xd4\xc0\xaf>\"\x18\xb7\xf5k\xe8\x99\x03\xadW\xab\xce\xf0TT\xda\x0fCr\x86\x1fV\xb9>\xcc&\xb1\x8f\xb4jq\x87vE\xa6\xabUԽaԜ\"\xaeT0u\x86\xeera5C\xfbM\x1cː^\x9e`\xe5\a\xa1\x19q4\xae;ZȜ\u007f$\x03\xc2\xfaB\x98\xb2\xb5\xdc\xe2\x10h\x99\x92\xe8\\\xbf\xbb\xf9\f\xd3\xd19\x19\xf3\xe8\x17\xe6\xec7\xd2!\x05\x120\xe3\xb6\x18K\x123\xf3\xc4'\xba6x\xe38\u007fhk\xd0\xcd\xc3Oi3\x18\xa6\x89̒\xab\x06\xae\xb2\xd2\xc0\x06!\x85V1\xb6\r\xbcwp\xa5\x06\xb4W\x8a\xf0\u007fO\x80D\x9aj\t\xec\xf3Rp,\x92s\xe3\x12\xb5\xa3\x85I\xc9.\xe4kV\xea7\x01\xb5dO\x02(;\xcd\xd6\xe8\\\x1a\xb0\xf5\x11ԡ\xf2\xc7\x006'\x9e\x97+7\x83S\xb1C\x9e\xcfΰ|\xceFr\xfc}\xafN\x85\xe6[l\xbaF\xb4\x82F E=\xbek\xce<^\xc6\x00\x8b\xec]D2\x91X\xc2 q\x15)\x10\x91:\xc6t~\xb4\ftiX>\xa0\x86\x9f3\xe6\x0f\xbe{t\xfd\xca;\x16\xba?jt\xebm\x1a\xf0Ʃ@\xbd\u007f\xc2\xf6=\xe3\xf0<\xcb\xe9A\xde?R\xe7\x86\xd7(R\x8e\x97/1\x1a\\#%{\xe1\xb8\v\xb4\x9eF~\xbe\x9eΑ<\x80S\x8edK\xd1t\x04i\v\xa2CF:\xc8˽\xe1~\xd1#\xc0}ot\x9f7\xe6\x04\x8br\x11ym\xb2\x0e|=|\xa9\v\x13q\x81du&\xdf´\x80?\x9b\xbeP͗\x0e\xa8\xc7\n{\x96\"\xb0\xe2D_\xa1\t\xd9~\n\xb5N1\xa2\xe3\xd1K~#\xe7\x1b\x9e+\nS%\xfdv\xfd\xe1\tex{\xb0\xcc]\xa02\xae\xa0\t\x11k2\x9d\xbc\xec\xb2&ڐk\xf6<\x18e\x9cv\x1a\xa7\x81Z\xcc(~\t&f\x05|\x02\u2efda\x110t\xe5q\x9a\xf7R\xd9!R~\xf8\xb5\x9a\xb7\x1c26\b-Zdla\xf3P\x94\xf8\x81\x18\x87s\xdc[\x1f\a\xc5k\x90G\xabf\xb3@#\xe9w\xd5\xc6\xe2\x1a8\xa6K,[\xbcx\xe8\x15-\x94\xe1ɝ?\x89\xcd\x121\xf6\xc5\xf8(3\xe0\xa2^\xd6\xf0\x11\xef\x17f?E\xaf\x91\b\xcf\xcb\xe8\xe2M\x16\x8b\xe0l\x92\xa4\xb3h\x8f\xa246\xac\xc73i\xb3\xef\x94&\xc4c)\xc1?\xffV\x87\xaaRZc`l?\xce\u007f\x14^\xbc8\xe9\xfc\xf3\xa7\xf6\xae5\xe5\x1f\a~\xff\xa3*\ac{;5\xf42\xf9_\x00\x00\x00\xff\xff\xcbT\xc3P]\r\x00\x00"), []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xc4YKs#\xb7\x11\xbe\xf3Wt\xad\x0f\x8a\xab\x96C\xdbI%)\xdev\xa58\xa5\xc4֪č.[{\x00\a\xcd!\xac\x19\x00\x010\xe42.\xff\xf7T\xe31\x9c\aHJ\xaa\xac3\x17\x89x4>4\xfa\xf150\x9b\xcf\xe73\xa6\xc5#\x1a+\x94\\\x02\xd3\x02\xbf8\x94\xf4\xcb\x16O\u007f\xb5\x85P\x8b\xdd\xf7\xb3'!\xf9\x12\xae[\xebT\xf3\x80V\xb5\xa6\xc4\x1b\xdc\b)\x9cPr֠c\x9c9\xb6\x9c\x010)\x95c\xd4l\xe9'@\xa9\xa43\xaa\xae\xd1\xcc+\x94\xc5S\xbb\xc6u+j\x8e\xc6\vOK\xef\xbe+\xfeR|7\x03(\r\xfa\xe9\x1fE\x83ֱF/A\xb6u=\x03\x90\xac\xc1%h\xc5w\xaan\x1b\\\xb3\xf2\xa9ն\xd8a\x8dF\x15Bͬƒ\x16\xad\x8cj\xf5\x12\x8e\x1dan\x04\x146s\xaf\xf8\xa3\x17\xf3ދ\xf1=\xb5\xb0\ue7f9ޟ\x84u~\x84\xae[\xc3\xea)\b\xdfi\x85\xacښ\x99I\xf7\f\xc0\x96J\xe3\x12\xee\b\x86f%\xf2\x19@ܻ\x875\aƹ\xd7&\xab\uf350\x0e\xcd5IHZ\x9c\x03G[\x1a\xa1\x9d\xd7ֽ\xe2\x10\x00B@\b\xd61\xd7Z\xb0m\xb9\x05f\xe1\x0e\xf7\x8b[yoTe\xd0\x06x\x00\xbfX%\xef\x99\xdb.\xa1\b\xc3\v\xbde\x16coP\xef\xcaw\xc4&w \xd0\xd6\x19!\xab\x1c\f:#\xd8oQ\x82\xdb\n\va\xb7\xb0g\x96\xe0\x18\xe7w\x99_\xd8\xf7wG<@pM\x06\xd0M\r\x108s\x98\x03\xd0\xe9\x13\xd4\x06\xdc\x16I\xf3\xde☐BV\xbe)\x9c\x048\x05k\xf4\x10\x91C\xab3\xc84\x96\x85V\xbc\x90I\xe8\x00\xd6ݨ\xf5\x92nh\xfc\xff\x1a\xd5\x00н⯀\xf2\xa2u\xc3\xe0\xc1\xaa\x8f\xfd\xa6K\v?\xa0u\xa2\x04\x83ZY\xe1\x949\x80\xe0(\x9d\xd8\b4\xb0Q\xa6o6' \xd0\xdc\xdbn\xd2\x00J\x94\xfe\x80Z\xbdB\x11\xd1oVN\x19V!\xfc\xa4J\x1fvȜ\r\x0e\xec\xd9nU[sX\xa7]\x03X\xa7Lָ\tq\x98\x15\xe5&\xb1#\x1f\x1b\xaey\x1a}Ov\n\xb2\xc5$@\x0ed\xbf\xab0\xef9\xa1{\xf7}\bU\xe5\x16\x1b\xb6\x8c#\x95F\xf9\xee\xfe\xf6\xf1\x8f\xabA3\x806J\xa3q\"\x85\xce\xf0\xf52F\xaf\x15\x86\xaa\xbe\"\x81a\x14pJ\x15h\x83\xfd\x856\xe4\x11C8\x0ea\xc9H\fZ\x94\xae\xaf\x92\xf4\xa9\r0\tj\xfd\v\x96\xae\x80\x15\x1a\x12\x93\x0e\xa6Tr\x87Ɓ\xc1RUR\xfc\xa7\x93m\xc9\xcciњ9\x8c\x11\xfc\xf8\xf9 +Y\r;V\xb7\xf8\x16\x98\xe4а\x03\x18\xa4U\xa0\x95=y~\x88-\xe0ge\x10\x84ܨ%l\x9d\xd3v\xb9XT¥LY\xaa\xa6i\xa5p\x87\x85Ozb\xdd:e\xec\x82\xe3\x0e\xeb\x85\x15՜\x99r+\x1c\x96\xae5\xb8`Z\xcc=t\xe9\xb3e\xd1\xf0oḼ\xf6j\x80ub\x18\xe1\xf3\x89\xec\xcc\tP*\x03a\x81ũa\x17GE\xa7P\xf4\xf0\xb7\xd5GHK\xfb\xc3\x18k\xdf\xeb\xfd8\xd1\x1e\x8f\x80\x14&\xe4\x06\xa3+o\x8cj\xbcL\x94\\+!\x9d\xffQ\xd6\x02\xe5X\xfd\xb6]7\xc2ѹ\xff\xbbE\xeb\xe8\xac\n\xb8\xf6\xf4\x81BS\xab\xc9ry\x01\xb7\x12\xaeY\x83\xf55\xb3\xf8\xd5\x0f\x804m\xe7\xa4\xd8\xe7\x1dA\x9f\xf9\x8c\a\a\xad\xf5:\x12=9q^#α\xd2X\xd2\xe9\x91\x02i\xa6؈\x18\xa1(p\xb2\xf1\xf0b 8\xef\xb8\xf4e\xa3\xd3x\xd0\b\xd9\xfbܜ\x84M\xf6bj\n\x98a\xe4D(@=\x8e\xb2d\x8e\x93\x1cac\x80-&\x12N\x1c\x03}Rq\xbc\xb0\x8f;\xc51\a\x9b\xa6\x82۲`\xadĭ(\x1e\xb5RNW\xa1O\xc9\x17\x01ӊ_\xc0\x15Wd`p\x83\x06e\x89)p\x9d#\x0e\x19d\xfd\x94>\xc5x\xda(\xe0LT\xcf\"~w\u007f\x9b\"yRb\xc4\xee\xa6\xeb^\xd0\x0f}\x1b\x815\xf7\x89\xee\xf2\xdaW\xb7\x9b\xb0\x98\x8fiN\x01\x03-0P\xc0.I\x80\x90\xd6!\xe3\xa06Y\x89T\xa8\x009\xbe\xc18\xe3m\x88`1T\x1eS\v\xe9\x1e\x18\xc5N\xc1\xe1\x1f\xab\x0fw\x8b\xbf\xe7T\xdf\xed\x02XY\xa2\xf5\f\xd8a\x83ҽ\xedH9G+\fr\xa2\xd8X4L\x8a\rZW\xc45\xd0\xd8O?|\xcek\x0f\xe0Ge\x00\xbf\xb0F\xd7\xf8\x16D\xd0x\x17\x96\x93\xd1\b\x1b\xd4\xd1I\x84\xbdp[1N\xa6\x9d\x06ȼ\xe2\xb6\xf7~\xbb\x8e=!\xa8\xb8\xdd\x16\xa1\x16O\xb8\x847\x9e\xd6\x1ca\xfeJ\xbe\xf3ۛ\x13R\xff\x10\\\xfb\r\rz\x13\xc0uy\xb8\xeftG\x90\xc1\xf3\x8c\xa8*<\xb2\xaa\xf1\xe7\x93\n\x85\xeaoA\x19ҀT=\x11^0\x9d^\b\x94\xc8'\xa0?\xfd\xf0\xf9$⡾@H\x8e_\xe0\a\x10\xb1\xacъ\u007f[\xc0Go\x1d\a\xe9\xd8\x17Z\xa9\xdc*\x8b\xa74\xabd}\xa0=o\xd9\x0e\xc1**\x92\xb0\xae\xe7\x81\aqس\x03i!\x1d\x1c\xd9\x1b\x03͌;k\xad\x89\xfd|\xfcp\xf3a\x19\x90\x91AU>\x12S\xd6\xdc\bb3DcB.\xf6\xd68I\xe6\xe9\xb3m0\x1f\xa7\xa0\xdc2Ya\xd8/¦\xa5\xecX\\\xbdƏ\xa7\x94$}\x19j2\x0e\x1c\xff\xb7\xe4\xfe\xcc\xcdy\x06\xfd\x8c\xcd\xf5\xab\x8c\xb3\x9b{j\xd7h$:\xf4\xfb㪴\xb4\xb5\x12\xb5\xb3\v\xb5C\xb3\x13\xb8_\xec\x95y\x12\xb2\x9a\x93i\u0383\r\u0605/Q\x17\xdf\xf8?\xafދ\xaff\x9f\xbb\xa1A\x95\xfd5wE\xeb\xd8ū6\x958\xec\xf3\xf3\xd8\xd5*2\xab\xf1\\r\x8b\xfdV\x94\xdbT\x9c\xc4\x18{\u0099\x041a\x1eB3\x93\x87\xafnʤ\xd0\xd6\x10\xa2\xc3<^\xb0͙\xe4\xf4\xbf\x15\xd6Q\xfb\xab4؊g\xb9\xef\xbfno~\x1f\x03oū|\xf5\x04\x01\x0f6ҿO\xb8@\xcc\x1e\x06\x83\x13u\xcc0\xd6n̋\x98\xa1cU\x86\x8a\xf5/\x02\xcf\x11\xb6\xb3\x1a\x18^ӱ\xca\x023\b\f\x1a\xa6\xe9\xe4\x9e\xf00\x0f)^3A\xf9\x99Rpw\xcf\x01L\xebZdSqL䑄F\xbeO\x856\xab쩽g\xcf!H\xb8\xa0\xffxř\xa1\xec\x11@\xe07\x1dm\xf7\xb7Z9^|\x9a\x14\x9f\xd4\"ե\xc4ֆ\x10\xe7\xf9\x02j4\x86\n\x8aQ\x93V|Ԓ\xbd\xd9J\x9d\x83\x9b\xb7\xb3\xca\f\x17\xaa/\xa8+\xc3Eq\xd4i\x88\".]\x1f\x13\x85~meY*b\xa7ë\xfb\xf3\xc7{=\x9d\xe1/q\f\x0f\xe0\x9ch\xc8f{\xd7\xcaq\x8d\\i\b=qa\xa6\x8f\xdb$\r\xb9\xa7\x8e\xc4l7L\xd4\xc8!\xbd\x1d\x8c\xe7d\xa4\xf6\xa5\xacqCA\xaeյb<\x15d\x11^GϨ^\xf7\xb7#W\xf6\x8c\xcc\xd6\"\xf7\x95|F\tSʶQ\xa6a.\xdc\xe6ͳBe[\xd7l]\xe3\x12\x9ci\xa7\xddg\x82E\x83ֲ\xea\x92+\xfe\x1cF\x85:5N\x01\xb6V\xad\xeb\n\xd5AP\xb8\xb2Ѧ^V+gK\xc0\xa193\xa2\xe86Rպ\xf6s\xfa\x81\xe0\xf8\xe0\xe4Q\xad1\x9f\xea^\x13\x13\x00\xfc\x83\xc9%\x844&\xe7`]\xf4:\xeba\xf4\xa1l\x9b\xe9*s\xb8\xc3}\xa6u\xf2\xd0\xd3\xef\xbcN.\x93\xe9\xfb\xd1{Ë\xf6\x1f\x17\xba\xa4\x828\f\xb6\xaaNά\x1c\xabA\xb6\xcd\x1a\r\xe9a}ph\x87\xe1n\xe6r\xd0\n53\xe4\xe9\xfe&\xfcz\xfcT\xf3\x16\xac\xf0\xd7{ķ\x02\x01\vŷ\xa5\xe4D\xc4R\x19̄L\x98\xa6\x95A\x12\x19\xc2\xff=\xf3G\xd6N&\x8d\x1e9\xefɎW\xc4\xfd\x96v\xdd=\u007f\xa4Ê\xdc\x06~\xfdmv\xa49\xac\xa4\x02\x02\xf9\xdd\xf8I\xffM\xb8\xe0Io\xf4\xfeg\xa9d`\xd3v\t\x9f>\xcf\xd2\xd3\xddczz\xa7\xc6\xff\x06\x00\x00\xff\xff\xb6\xe8a\xa8\a!\x00\x00"), []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xc4YKs\xe3\xb8\x11\xbe\xebWty\x0f\xceV\r\xa9\xddI*I\xe9\xb6kgSJv=\xae\x913\x97\xa99@DS\xec\x98\x04\x18\xa0)YI忧\x1a \xf4\xa4\x1ev\xd5Lx\xb1\x85G\xe3\xeb\xaf\x1f\xe8&GY\x96\x8dTK\x9f\xd0y\xb2f\x02\xaa%|a4\xf2\xcb\xe7\xcf\u007f\xf69\xd9\xf1\xf2\xc7\xd13\x19=\x81\xbbγm>\xa2\xb7\x9d+\xf0\x1eK2\xc4dͨAVZ\xb1\x9a\x8c\x00\x941\x96\x95\f{\xf9\tPX\xc3\xce\xd65\xbal\x81&\u007f\xee\xe68\xef\xa8\xd6\xe8\x82\xf0t\xf4\xf2\x87\xfcO\xf9\x0f#\x80\xc2a\xd8\xfeD\rzVM;\x01\xd3\xd5\xf5\b\xc0\xa8\x06'\xd0Z\xbd\xb4uנC\xcf֡ϗX\xa3\xb39ّo\xb1\x90S\x17\xcev\xed\x04\xb6\x13qs\x8f(j\xf3h\xf5\xa7 \xe7c\x94\x13\xa6j\xf2\xfc\xf7\xc1\xe9_\xc9sX\xd2֝S\xf5\x00\x8e0\xeb\xc9,\xbaZ\xb9\xe3\xf9\x11\x80/l\x8b\x13x\x10(\xad*P\x8f\x00z\x02\x02\xb4\xacWq\xf9c\x94UTب\x88\x19\xc0\xb6h~z\x9c~\xfa\xfdlo\x18\xa0u\xb6EǔԋώYwF\x014\xfa\xc2Qˁ\xf4[\x11\x18W\x81\x16{\xa2\a\xae0\x81B\xddc\x00[\x02W\xe4\xc1a\xebУ\x89\x16\xde\x13\f\xb2H\x19\xb0\xf3\u007fb\xc19\xccЉ\x18\xf0\x95\xedj-n\xb0D\xc7ర\vC\xff\xde\xc8\xf6\xc06\x1cZ+ƞ\xe3\xedC\x86\xd1\x19U\xc3R\xd5\x1d\xbe\x03e44j\r\x0e\xe5\x14\xe8̎\xbc\xb0\xc4\xe7\xf0\x9bu\bdJ;\x81\x8a\xb9\xf5\x93\xf1xA\x9cܹ\xb0M\xd3\x19\xe2\xf58x&\xcd;\xb6Ώ5.\xb1\x1e{Zd\xca\x15\x151\x16\xdc9\x1c\xab\x96\xb2\x00\xdd\x04\x97\xce\x1b\xfd\x9d\xeb\x03\xc0\xdf\xeea\xe5\xb5\xd8ֳ#\xb3ؙ\b\xcev\xc6\x02\xe2m@\x1eT\xbf5j\xb1%Z\x86\x84\x9d\x8f\u007f\x99=A::\x18\xe3\x90\xfd\xc0\xfbv\xa3ߚ@\b#S\xa2\x8bF,\x9dm\x82L4\xba\xb5d8\xfc(jBsH\xbf\xef\xe6\r\xb1\xd8\xfd_\x1dz\x16[\xe5p\x17b\x1c\xe6\b]\xab\x15\xa3\xceaj\xe0N5X\xdf)\x8f_\xdd\x00´τ\xd8\xebL\xb0\x9b\x9e\x0e\x17G\xd6v&R\n9a\xafô0k\xb1\x10\xf3\t\x83\xb2\x95J*Bl@i\x1d\xa8\xa3\xf5\xf9\x9e\xe8\xe1Еg\xae\x8a箝\xb1uj\x81\xbf\xda(\xf3p\xd1\x01\xb6\x9f\x87\xf6$p\x92Yb\x18c/\x1c|\\y$\x14\xa0N\x9bW\x15:\f{$\x8bQ!\xeee=\xb1uk\x11\x1cT\xd2\xf9\x91\x84\x13\x86\b*[}A\x8dG\xdb\a\x84\xc3\x12\x1d\x1aq\xf7\x98!Z\x1b\xf2\b+2),b\x8a\x05\xb6\x03Z\xcc#\xeaa\x88\xa7\xa9\x873\xd9s\x10\xf0O\x8fӔ1\x13\xc3=t>>\xf7\x02=\U00094135~T\\]q\xf6\xed\xb4\x8c\x87\x85\xdc\xc1\x16\x14\xb4\x84\x05\xee%c \xe3\x19\x95\x06[\x0eJ\x94[\x1b$\xc0\x1c\xf6;\xde\xc5Lѧ\xa4m\n\x17\xeaAI\x8e\"\r\u007f\x9b}x\x18\xffu\x88\xf9\x8d\x16\xa0\x8a\x02\xbd\bR\x8c\r\x1a~\a\xbe+*P^\xd4 \x87z&3y\xa3\f\x95\xe89\xef\xcf@\xe7?\xbf\xff2\xcc\x1e\xc0/\xd6\x01\xbe\xa8\xa6\xad\xf1\x1dPd|\x93\xfe\x92ϐ\x8ftl$\u008a\xb8\xa2\xc3KkÀxW\xaf\xf6*\xa8\xcb\xea\x19\xc1\xf6\xeav\b5=\xe3\x04n$\xcaw`\xfeG\x02\xeb\xbf7'\xa4\xfe.\x06Ѝ,\xba\x89\xe06\xf7\xddnDnAr\xa5\x18\xd8\xd1b\x81.\x14\bCOHޒ\x12\xbf\a\xeb\x84\x01cwD\x04\xc1b\xbd\x98\x8fP\x1f\x81\xfe\xfc\xfe\xcbI\xc4\xfb|\x01\x19\x8d/\xf0\x1e\xc8DnZ\xab\xbf\xcf\xe1)x\xc7ڰz\x91\x93\x8a\xcaz<Ŭ5\xf5Zt\xae\xd4\x12\xc1\xdb\x06a\x85u\x9d\xc5zC\xc3J\xad\x85\x85d8\xf17\x05\xadr|\xd6[S\x95\xf1\xf4\xe1\xfe\xc3$\"\x13\x87Z\x84|'\xb7SIR5H\xb9\x10\xef\xbc\xe0\x8dG\x97fz|\x17݇-\x14\x952\v\x8c\xfa\"\x94\x9d\xdcB\xf9\xed[\xe2\xf8\xf8\xeaO\xcf@\tp\x988\xfeo\x97\xe8\x95ʅJ\xf5\n\xe5\x1ev\xbc\xfc\xacr\xd2\x188\x83\x8cA?m\v/\xaa\x15ز\x1f\xdb%\xba%\xe1j\xbc\xb2\xee\x99\xcc\"\x13\xd7̢\x0f\xf8q(\xed\xc7߅?o\xd6%\x14\xe4\xd7*\x14\x16\u007f\v\xad\xe4\x1c?~\x93R\xa9V\xbc\xfe\x1e\xbb\x9d\xf5\x05\xcc\xe1^\t\x8bUEE\x95\x9a\x80>Ǟ\b&\x92\x8aS\xc7Ԭ\xcc\xfa\xab\xbb\xb2\x10\xda9A\xb4\xce\xfan3SF\xcb\xff\x9e<\xcb\xf8\x9b\x18\xec\xe8\xaa\xf0\xfd\xc7\xf4\xfe\xdb8xGo\x8a\xd5\x13\x85n\xf4\x91\xd6N\xb5PY\x12\xba\vu\xd9ǽũ\xae\x1c\xa8\v7k^U\x18z\xa3Z_Y\x9e\xde_\xc01\xdb,L\x18\xb6\x06\xe8\xcb\xc1$K\x1c\xf7l\x15x\x06O\x14u\x01K\xac\xed\x87j\xec\x1eI\xac9\u0088Ե\x01\xcfp\xb0\xbe\x16\xa1\xb4dR@\xed#̆;\x87\x835\xad\xd5\a#\xfb\x9ep0\xb95\xcd\xc1DT\U000aad8a\x15w\xfe5\x8dUؐ\x98\x8d\xf1ͽ\x98Pܾ\xb9\xb5*\xac\x14\x8e\xfb\xaf\x98\xce[\xf9\xeexGx\x8f\xe1tD\xc7\xd4`\xe8W\x02\x0eX)\x9f\x0e\x19\xb2(\xecȋ[CN\x15q\xa8CY'Ug\xa9\xa8F\r\x9b\x97\\\xf0$\x1dfh\xe8o\x87\xaa\x98$\xa8\xf3\xa8C\xef9\x00\xfax_i]\xa3x\x02\xd2\xc6g\"\xe2h\x85\xe9\xeaZ\xcdk\x9c\x00\xbb\xeex\xfaL\x005\xe8\xbdZ\\\x8a\xa0\xdf\xe2\xaa\xd8\xf1\xf5[@\xcdmǛ\x96\xaf\x0f\xa5\x9e\x8a[\xdf{\xc1\xeb\xda\xceJ\xf9KP\x1ee͐\xc7m\x82\xfa\xbc\xcbɃ\xa6k\x8e\x8f\xc9\xe0\x01W\x03\xa3S\xf3\xe8\xec¡?\xb6L\x96\f8\xd0\x04d\xf0K\xf0\x8eW\x11\xd0\x1ft\x89\x83~\x19T\xb6N\xdemY\xd5`\xbaf\x8eN\x88\x98\xaf\x19}b$\xa5\x86\xa1\x1e:\xd4\xde[&\xb7\x12R\xb6\x8b\xa2\xfan\xa2P&\xbcR\x12\xffe\v\x9a|[\xab\xf5\x80ܤI\xb8^\xc5}%\x8e\xb6\x1e\x93\xa2P\xc2?̽\xb6\xf7\x0f\xa0\xee\xad9Q\r\xa6\x90!\xc3\u007f\xfcÙۘ\f\xe3\xe2 \x95\xf6\xf3B\xe8\xcfr\xca\xd79\xe1̅\xefY9\xbe6\xed\xcd\xf6\x16_\xcaxA\xf4p\xbe\xdbM]ljj\xff\x98o\x99\xa3\x06\x89:\x1a\f\xc8\xf5\x8e\xec\xfe\xbdY?\xb2\xbd\xd9T!\xc5\x1c\xea\x87\xc3O\r77{_\x0e\xc2\xcf\xc2\x1aM\xf13\t|\xfe2\x82\xfe]ڧ\xf49@\x06\xff\x17\x00\x00\xff\xffñ\x1b\xae\xa0\x19\x00\x00"), - []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xb4W\xc1n\xe36\x10\xbd\xfb+\x06\xdb\xc3^*y\x17=\xb4ЭM[ h\x12,\x9cE.E\x0f\x145\xb2\xa7\xa1H\x96\x1c:u\xbf\xbe\x18J\x8aeY\x897\v\xacn&g\x1e\xdf̛\x19ҫ\xa2(V\xca\xd3\x03\x86H\xceV\xa0<ῌV~\xc5\xf2\xf1\xa7X\x92[\xef?\xae\x1e\xc96\x15\\\xa5Ȯ\xdb`t)h\xfc\x15[\xb2\xc4\xe4\xec\xaaCV\x8dbU\xad\x00\x94\xb5\x8e\x95,G\xf9\t\xa0\x9d\xe5\xe0\x8c\xc1Plі\x8f\xa9\xc6:\x91i0d\xf0\xf1\xe8\xfd\x87\xf2\xc7\xf2\xc3\n@\a\xcc\ue7e9\xc3Ȫ\xf3\x15\xd8d\xcc\n\xc0\xaa\x0e+\b\x18\x99t@\xef\"\xb1\v\x84\xb1ܣ\xc1\xe0Jr\xab\xe8Q˱\xdb\xe0\x92\xaf\xe0\xb8\xd1{\x0f\x94\xfap6\x19h3\x02\x1d\xf2\x96\xa1\xc8\u007f,n\xdfP\xe4l\xe2M\n\xca,\x11\xc9ۑ\xec6\x19\x15\xce\f䀨\x9d\xc7\n\ue10bW\x1a\x9b\x15\xc0\x90\x82̭\x18\x82\xdc\u007f\xec\xb1\xf4\x0e;Փ\x06p\x1e\xedϟ\xae\x1f~\xb8?Y\x06\xf0\xc1y\fLc|\xfd7\x11v\xb2\n\xd0`ԁ<紿\x17\xc0\xde\n\x1aQ\x14#\xf0\x0eGR\xd8\f\x1c\xc0\xb5\xc0;\x8a\x10\xd0\a\x8ch{\x8dO\x80A\x8c\x94\x05W\xff\x8d\x9aK\xb8\xc7 0\x10w.\x99F\na\x8f\x81!\xa0v[K\xff=cG`\x97\x0f5\x8aqH\xf2\xf1#\xcb\x18\xac2\xb0W&\xe1\xf7\xa0l\x03\x9d:@@9\x05\x92\x9d\xe0e\x93X\u00ad\v\bd[W\xc1\x8e\xd9\xc7j\xbd\xde\x12\x8f\x05\xad]\xd7%K|X\xe7ڤ:\xb1\vq\xdd\xe0\x1e\xcd:ҶPA\xef\x88Qs\n\xb8V\x9e\x8aL\xdd\xe6\xa2.\xbb\xe6\xbb0\xb4@|\u007f\u0095\x0f\xa2m\xe4@v;\xd9\xc8\xd5\xf6\x8a\x02Rn@\x11\xd4\xe0\xdaGqL\xb4,Iv6\xbf\xdd\u007f\x86\xf1\xe8,\xc6<\xfb9\xefG\xc7x\x94@\x12F\xb6\xc5Ћ\xd8\x06\xd7eL\xb4\x8dwd9\xffІ\xd0\xce\xd3\x1fS\xdd\x11\x8b\xee\xff$\x8c,Z\x95p\x95\xbb\x1cj\x84\xe4\x1b\xc5ؔpm\xe1Juh\xaeT\xc4o.\x80d:\x16\x92\xd8/\x93`:\xa0\xe6\xc6}\xd6&\x1b\xe3\fyA\xaf\xf9\\\xb8\xf7\xa8E>ɠ\xb8RK:\xf7\x06\xb4.\x80:\xb3/O\xa0\x97[W\xbeZ\xe9\xc7\xe4\xef\xd9\x05\xb5\xc5\x1b\xd7c\u038df\xdc~Y\xf2\x19\xc9\xc9d\xe9\xdb\x18\x97\rϰ\x01x\xa7xҿ\xac\xc8>\x8f\x81\xc5x^\x11!\v\xa1\xa4\x9d\xad\xb2\x1a\u007f\xcf\x15e\xf5\xe1BL\xb7\v.\x12\xd2\xce=\x81k\x19\xed\x14t\xe0\xba\x10I\x8d\x10\x92}\x13\xd9~~_7Rx-a\xb8@t33\x1f\xf3\xde&c\x06\xacB\xbb\xce+\xa6\xda\xe0\xf2\x91\xf2I\xd9P\x8fr\xe8{\xff\xeb\xf3\xbdw&u\xf8|\xdd\\\x88\xe0\xe1\xd4zZ8\xfd\xc2@EB\x81pzq\x9e~C\xadD\xf0\xae\x19H\f\x05\x1d%\xbe7\xc4 \x92S\xc0\xd9\x04-\x96\xdbcf\xb3Tm3\x93\xb9Ƴ\xedY\xfe\xbeh|\xb0\xe2\x14\xdf2@\xb2Øl\x9dB@\xcb\x03L\xbeQ\xbfz\x84\x18\x15y\xd2>\xf2\xa2\xbaP\x017\xe7\x1e#1\x01\x03\x96\x85i\xbf=\xa9\xf9-\x94E[\xea\xb4օNq\x05ra\x14\x02tf!\xef-\xacnP5\xe7}\\\xc0\x9d\xe3\xe5\xad\x17#\\슳\xc5(\xef\x92f\xa2s\xec\x1byX9\xf6\x90\xd2\x1a=cs7\u007f\xbd\xbf{w\xf2\x18\xcf?\xb5\xb3\r\xf5\u007f=\xe0ϿV=*6\x0f\xe3\x03[\x16\xff\x0f\x00\x00\xff\xff\x83\xf9\xd9\xe0\xf4\f\x00\x00"), + []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xb4WM\x8f\xdc6\x0f\xbeϯ \xf2\x1e\xf2\x16\x88=I{h\xe0[\xbai\x81\xa0\xc9f\xb1\x1b\xec\xa5\xe8A#Ѷ\xb2\xb2\xa4J\xd4l\xa7E\xff{Aɞ\x0f\x8f\x93I\x02\xd47\x89\x1f\"\x1f\xf2\xa1\xe4UUU+\xe1\xf5=\x86\xa8\x9dm@x\x8d\u007f\x12Z^\xc5\xfa\xe1e\xac\xb5[o_\xac\x1e\xb4U\r\\\xa5Hn\xb8\xc5\xe8R\x90\xf8\x1a[m5igW\x03\x92P\x82D\xb3\x02\x10\xd6:\x12\xbc\x1dy\t \x9d\xa5\xe0\x8c\xc1Puh뇴\xc1M\xd2Fa\xc8Χ\xa3\xb7\xcf\xeb\x1f\xeb\xe7+\x00\x190\x9b\u007f\xd0\x03F\x12\x83o\xc0&cV\x00V\f\xd8@\xc0HZ\x06\xf4.jrAc\xac\xb7h0\xb8Z\xbbU\xf4(\xf9\xd8.\xb8\xe4\x1b8\b\x8a\xf5\x18RI\xe76;\xba\x9d\x1c\xed\xb2\xc8\xe8H\xbf.\x8a\xdf\xeaHYś\x14\x84Y\n$\x8b\xa3\xb6]2\"\x9c)\xf0\x01Q:\x8f\r\\s,^HT+\x80\x11\x82\x1c[\x05B\xa9\f\xaa07A[\xc2p\xe5L\x1a&0+\xf8\x18\x9d\xbd\x11\xd47PO\xb0\xd7g\x90e\xdd\t\xb0W\x1d\x8ek\xda\xf1\xe1JP\xd9(\xe2\xed\x8b\x12\xb6\xecq\x10ͨ\xe9<\xdaW7o\xee\u007f\xb8;\xd9\x06P\x18eОr\xcd>\xbc\u007f\xfd\xfe\xff\xdf\xd7Ͽ\x83W-a\xe0Ro1\x90\xb6\x1d\bc8\xff\xdc)\x11\xc8A\x8a\b\xd4#\x84dI\x0fX\x1d\xdab\xef\x1b@\x1a\x8d\x96\x9ee\xc5\x0emY\x82\xb0\n\x1e^\xc6F!z\xe9\xfc\x0e\x06\x11\x1e0Dx\xd4ƀu`\x9c\xed0\xc0\x06\xc1\"\xaa\f\xea\xf4\xb1m\xec]2\x8a\xc5\x01\a\xb7EU\xef\x15|p\x9e#\x9e:c4:P\xe2hw\x96\xfcSƧh\x81b.p\x9e=N\xe5D5B\n\xae\x05\xeau\x84\x80>`D[\xd8q\xe2\x18XIXp\x9b\x8f(\xa9\x86;\f\xecf\x8a|\xc4\x15\x02J\xd7Y\xfd\xd7\xdewF\x96\x0f5\x82pl\xcf×\xdb\xc7\n\x03[a\x12>\xcbX\fb\a\x01\xf9\x14H\xf6\xc8_V\x895\xbcs\x01A\xdb\xd65\xd0\x13\xf9جם\xa6i\x14H7\f\xc9jڭs\xf9\xf4&\x91\vq\xadp\x8bf\x1duW\x89 {M()\x05\\\v\xaf\xab\x1c\xba\xcd\xe3\xa0\x1e\xd4\xff\xf6-\xf1\xf4$\xd6Ҙ\x91\x82\xb6ݑ \xf3\xf43\x15`\xa2\x82\x8e FӒ\xc5\x01h\xdebtn\u007f\xbe\xfb\xb0\xef\xc6\\\x8c9\xfa\x19\xf7\x83a<\x94\x80\x01Ӷ\xc5P\x8a\xd8\x067d\x9fh\x95w\xdaR^\x94F\x9d9\x8di3h\xe2\xba\xff\x910\x12ת\x86\xab<\x1f\xb9\x17\x93g\"\xaa\x1a\xdeX\xb8\x12\x03\x9a+\x11\xf1?/\x00#\x1d+\x06\xf6\xcbJp<\xda\xe7\xca\x05\xb5#\xc14}?Q\xaf\xf9D\xbd\xf3(\xb9|\x8c \x9b\xeaV\xcb\xcc\rh]\x00q\xa6_\x9f\xb8^\xa6.\u007f\x1b!\x1f\x92\xbf#\x17D\x87o]\xf19W\x9a\xc5\xf6Ӓ\xcd\x14\x1c\x0f\xcaBc\\V<\xf3\r@\xbd\xa0#\xfe\x92\xd0v?\x06\x16\xf3\xf9L\x11r!\x04\xd3\xd9\n+\xf1\x97\xdcQV\xee.\xe4\xf4n\xc1\x84S\xea\xdd#\xb8\x96\xd0\x1e;\x1dc]\xc8d\x93\x87\xf6W\x05[n\xbe7\x8a\x1b\xaf\xd5\x18.\x04z;S\x9fpoS\xb9EH\xcbJ\xba\xc1\v\xd2\x1b\x83\xcbG\xf2\xc7m\xa3\x8b\x97]\xe1\xfe\xb7\xe3\xbd\xe5k\x17\xf7\x17\xf5\x85\f\xeeO\xb5\x8f\x1b\xa7l\x8c\xa1p*\x10N\x9f\x1c\xa7\xdf\xd8+\x11\xbcSc\x10cCG\xce\xef+r\xe0\x92뀳\tZ-\xd3c\xa6\xb3\xd4m3\x95y\x8dg\xe2\x19~_4>HP\x8a_3@\xb2\xc1\x04\xb6L!\xf0s\xa1\xb8\xc97\xea7\x8f\x10#\"\x1dч\x1fV\x17:\xe0\xed\xb9\xc5\x14\x18;\x03~\xf4\x9c\xf0\xedQ\xcco\xa1\\\xb4%\xa6\xb5.\f\x82\xca˭bGg\x1a\xfcB\x16\x1b\x83\rPH\xe7\xe2\xcf\xcd\x15\x8cQt\x97\xb2{W\xb4\xcae;\x9a\x80ظD\x9f\x80\x9e\xfa\xf3(\xe0B9.D\xea{\x11/\xc5y\xc3:K\r\xb1\x9fߗC@\x9b\x86\xf3c*\xb8\xc6Dž\xdd[\x14\xea\x9c\xc7\x15\\;Z\x16}2\xc3EV\x9cmF~\x97\xa8\xa3:\xc7B\xe4㝴ٿ\xb3\xa6DFn\xc1\xdf\xff\xac\x0e4\x13R\xa2'T\xd7\xf3_\xa3'ON\xfet\xf2R:[\xfeLb\x03\xbf\xfd\xbe*\a\xa3\xba\x9f\xfe^x\xf3\xdf\x00\x00\x00\xff\xffo=\x1agQ\x0e\x00\x00"), []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xec\xbd}s#\xb7\x910\xfe\xbf?\x05Jq\xfd$]Dʛ\\\xf2\xbb\xdbJ=)eWvT\xf6jU+e\xfd\xa4\x1c\x9f\x0f\x9ci\x928\x81\xc0\x04\xc0P\xe2\x9d\xef\xbb?\x85\x060/\xe4\x90\"0Ծ\u0603\xab\xbax\xa9\x99\x1e\xa0\xd1\xe8wtӂ\xbd\a\xa5\x99\x14/\t-\x18<\x1a\x10\xf6_z|\xffoz\xcc\xe4\xf9\xf2\xc5\x17\xf7L\xe4/ɫR\x1b\xb9x\aZ\x96*\x83\xd70e\x82\x19&\xc5\x17\v04\xa7\x86\xbe\xfc\x82\x10*\x844\xd4\xfe\xac\xed?\tɤ0Jr\x0ej4\x031\xbe/'0)\x19\xcfA!\xf0\xf0\xe9\xe5W\xe3\xff\u007f\xfc\xd5\x17\x84d\n\xf0\xf5;\xb6\x00m\xe8\xa2xID\xc9\xf9\x17\x84\b\xba\x80\x97D\x816R\x81\x1e/\x81\x83\x92c&\xbf\xd0\x05d\xf6c3%\xcb\xe2%\xa9\xff\xe0\xde\xf1\x13q\x8bx\xe7^\xc7_8\xd3\xe6\xdb\xe6\xaf\xdf1m\xf0/\x05/\x15\xe5\xf5\xc7\xf0G\xcdĬ\xe4TU?\u007fA\x88\xced\x01/ɵ\xfdLA3ȿ į\t?;\xf2\xb3^\xbep \xb29,\xa8\x9b\x0f!\xb2\x00qqs\xf5\xfe\xf7\xb7\xad\x9f\t\xc9Ag\x8a\x15\x061\xe3\xe7F\x98&\x94\xbcǵ\xd9\t\xe0&\x103\xa7\x86((\x14h\x10F\x133\aB\x8b\x82\xb3\f\x91XA$DN\xab\xb74\x99*\xb9\xa8\xa1Mhv_\x16\xc4HB\x89\xa1j\x06\x86|[N@\t0\xa0I\xc6Km@\x8d+X\x85\x92\x05(\xc3\x02b\xddh\xd0Q\xe3\u05f5\xb5\x1c\xdb座Hn\t\bܔ=\xca \xf7\x18\xb2\xb35s\xa6륭/\xc7/\x89\n\"'\xff\x05\x99\x19\x93[P\x16\f\xd1sY\xf2\xdc\xd2\xdd\x12\x94EN&g\x82\xfdw\x05[ۅڏrj\xc0\xefw=\x980\xa0\x04\xe5dIy\tg\x84\x8a\x9c,\xe8\x8a(\xb0_!\xa5h\xc0\xc3G\xf4\x98\xbc\xc1\xed\x11S\xf9\x92̍)\xf4\xcb\xf3\xf3\x193\xe1\xfcdr\xb1(\x053\xabs<\nlR\x1a\xa9\xf4y\x0eK\xe0\xe7\x9a\xcdFTesf 3\xa5\x82sZ\xb0\x11N]\xe0\x19\x1a/\xf2\xdfT\xdbvܚ\xabYY\xca\xd3F11k\xfc\x01\xc9|\xc7\x0eX\x82w\xb4\xe4^u\xab\xa8\x11m\u007f\xb2\xd8ywy{פ3\xa6ױ\x8fxo\x10_\xbd\x05\x16aLLA\xb9MDj\xb30A\xe4\x85d\xc2\xe0?2\xce@\xac\xa3_\x97\x93\x053v\xdf\xffY\x82\xb6\x04-\xc7\xe4\x152\x152\x01R\x1695\x90\x8fɕ \xaf\xe8\x02\xf8+\xaa\xe1\xd97\xc0bZ\x8f,b\xf7ۂ&?\\\u007f\xd8a\xad\xf1\x87\xc0\xbc\xb6\xec\x97?\xfd\xb7\x05d\xad\x13c_cS\u007f\xcc\xc9T\xaa\x16s\xb0\xaf\x8c[@\xbb\x0f\xad\x1d\xee\xf4[\x0e\xb6\xfe\x97\xb5\xa9\xfc\xa5z\xd0ҏ\x9dD)\xd8?K@\x16\xe7N,l\xb0\x94\r\x90$\xcc\x0f\xc9b\xbc\xf1\xf7-8\xb5\x03\x1e3^\xe6\x90W\xdcvc-k3\xbe\xdcx\x01\xc5\x11e\xc2ҿe\xffvڢ\xfe\xabe\xa7\x1d3\xa6\n\x88\xa5@&\x1c<\xc2\x04.\xb6\x13\xd3v0\x03\x8b\x8e\xc9\xed\\\x1dA9G'\x1c^\x12\xa3J\u0602\x19\xaa\x14]mAL\x90\xcd\xfb\xe2\xa5z\xde3\x04\xce2h\n\n\x87\x1a'd\xa8ڜ\x11\xf9\xa4\xb12\x97\xf2\xfe)L\xfc\xd5>S\xf30\x92\xa1\x8eC&0\xa7K&\x95_\xbb\x17)\x13 \xf0\bYiP\xcco\xc0-\x91\x9dJE\n\xa9\xcdv,l?\x89\xc4\x1d\x8em[\xb8\x13\x85\x1b+\xf3\x8c#l\xb1]h\x8b\x89H\x01v\xae\v{\x12\xebg\x95,ݳ\xebܾ\x81\xf0n\x8c\x90\tՐ\x13\xe9i\xa0\xe4\xa0\xfd\xb7rdO\xf5);\xdb\n\xbaZ\xbc\x93\xbb\x9cN\x80\x13\r\x1c2#\xd5&&\xf7\xc1\xa7\x1b\xfbp\x8e-x\xec\xe0!\x9e\xf7zN\\/l\aHb\x95\x8e\x879\xcb\xe6N$Z\xdaD8$\x97\xa0\xf1\x18Y\xb5m\xb5m\x91䩽\xf7\x1f\xd9u\x90\xea\xf1đZ\x87\xd7u\xb8\xea\xb1\a\xf3\xa9\xc7\x13l\xa8\x8d\xd9Z_\xed\x94#\xf5\xf8e\"6\xf0\xd5\x04\xa2\xbd\xdax\xf5\xb0D\x8b&\x86U}\xaf\xa6\x04\x16\x85Y\x9d\x11f¯OA\xa4\x9c7\xbe\xff\x19oL<\xc5_\xad\xbfyP\x8a߹+OA\xb4\xbbR}\xfe3\xdc\x14\x14\x16\xb7^V\xec\xbd!\xdf5\xdf:#lZmH~F\xa6\x8c\x1bPk;\xd3\xeb\xbc\x1c\x02\x19\xfb\xc8;;\x16\xd4d\xf3\xcbG\xab\xd9\xe8\xda\x1d\xb3'^\xd6_v\nbИۂ\xf9\t\xb8\x04\x8d9\xa6`\xe1\x8c\xc4;\xc4f\xfd\vj\xd7\x17ׯ!߅\x1e\xb2\x1f\xe5m,\xe4bm\xb2\xcdO{\xadw\xdfexէ\xb2 \x9c\xf9\u007fF(\xb9\x87\x95\xd3X\xa8 vs\xa8\xfd\xd0\x16[b\x139\xe8\x87@\"\xbb\x87\x15\x82\xf1\x8e\x85'\xdfޗ\x14ܸ\x87\xd5>\x8f\xad!\xd0\xceɛ{\x0e\x93\xf6\aD\x04\x9a\xa1\xfb#\x8f\xa0\x93(\xf0\xa2\xa7\x17G\xf6g$a\x04\xdc',\xb3ڶ\x863\r7\xf6X\xbb-\xb2\xa7`Ί=\x17\x8a\xbe4\rxZ\x82\x9b\xe8=\xe5,\xaf>\xe4\xe8\xfeJl׆\xdb\xe3Z\x9a+qF.\x1f\x99\xb6S\x139y-A_K\x83\xbf<\v:\xdd\xc4\x13\x90\xe9^\xc4\xe3%\x1c۶xh\xfa\x9b\xf6 n7\xae\x9c[\xa1\xda\x1e\xa6ɕ\xb0\x86\x8b\xc7\az\x0f\xdd\xe7vˇ\xf6X\x94\x1a\x1dJB\x8a\x11\x8a\xcaqח\x1c\xb2\xf7\x04)UkG6\xa7V}\xd4}pO\xb0wV\x92\xb8\xf7\x9d?\x94\xd3\f\xf2`m\xa2\x17\x8f\x1a\x98\xb1\x8c,@\xcdv\t\x8e\xe6(,\u007f\xdfo\n{r]7\")l?\xd1\x1e\x86g\xdd\xf9ӓ\x19ٓ\xbb\xc7Sa\xb3\x9f|t\x8b\xf3n\xfb\xa3O\xaf\bE,\xea\x1fOb\x97\xe69FZ(\xbf\x89\xe0\xf8\x11{\xb1)\xfb\xddĜ\x84\\\xd0\u009e\xdf\xff\xb1b\x0e\t\xfa\u007fIA\x99\xda\xe3\f_`ЄC\xeb]\xef&j~\xc6~\x81ib\xf7wI\xf9\xa6[\xb8cq\xd2\xf2\x16\xe0N\x90\xcb\xe9\x86\xc6rF\x1e\xe6R;\x99:e\xc0\xbb\\6\xed\xc149\xba\x87\xd5\xd1\xd9\x06\x1f8\xba\x12GN\xc0G\xb3\x9bJ[\x90\x82\xaf\xc8\x11\xbe{\xd4G\tړ\x12\xf7zLt:}\xeb\xd1\"\x8b\xa6\xe3\xb7\xf6\xf8z5w\u05ec\xf7\xa2\xc3Bj\xf3\xd7n\x87ݖ\xf9܄7ںi\x87\xdf\xebI\x9d\xdd\xfb\xb0*\xa6j5\xb9\xa9\x01\xe5\x9dx\x8e\xd1\x06\v\xa0\xa7m\xf4\x94\x93\xaer\xd0\xd1\xcaQn\x11\xfc\x04U\xb8\x00\xc0>S\x8c\xd1\x1a-^\"\xf5\xed\xcbdž\x8fўP\xfb\xef\xe6B\x0e\xad\xd5fr\xb1\xa0\xeb!\xaf\xbd\xa6\xfaʽ\x19h\xda\x03r\xbb\xaff%\x9e\xcb\xfdս@C\x18\xecz`f\xce\x04\xa1\xe1\xf8\x83\xf2\x04EI!\x9f\xe6Dn̩&\x13\x00\x11\xd0\xf7$kp\xe3y\xe5\xf5\x82\x89+\xfc\x00yqp\xf9Njt%mg@u\xb5\xa1\xd5\x0f(q\xf6U\x8ddN\x1e栠E\x15\x9b\x0eo\xab1\xee\tRH\xd3\xf4+X\xb8\x85̏5\x992\xa5Ms\xa2\xfb\x12\\\xa9\xf7%\x87\xc8\x1d\xb6\xab\xbbc\v\x90\xa5I\u0603\xcb\xfa\xedV\xb4rA\x1f٢\\\x10\xba\x90\xe5\x1e\xc2\xdd\r+_آ\n)\xfa\x1dx\xa0\xcc \xbb\xb3p\xd1\xc3b\xa4ݥ\x82\x83\xd9w\x8b'0\xb5\xec(\x93B\xb3\x1cT\by\xbb\x9de\xd2\x1e\xdc)e\xbc\xec\n\xdft\x8dX3U\\*\x95d\xa5\xbeuo6\xbc\x86s\xf9\xd0F\xd0\xde(\x98\xd3%\x106%\xcc\x10\x10\x99\xdd\x17P\x8ee\xe3'<2\x105{\x93\xe5~\f\xde\x0e\x10\xe5b?\x04\x8c\xf0d3\xb1\xd3)\xd6|\xfck\xca\xf8sl\x9b\xa5\xbc\xf4\xa3\xf1}\xfd\xf6\a9\x1a\x15S\xd9_\x84M\x80\xbc\x03\x9a\xaf\xc2\xf9\xa0\xc6XS\x15i@\x12U\x8a&G|\x86\x93\x11c\xdf\xf9Y\x1c\xd2pc\x82\xed\xb1\xb1k\xfe|f\x9aڎ\x05\xf1\xacڎ\xfd@%\xe8R\\3W-\x00VT\x06\xc5\x19\xe7^QM\x84\xe63\x01k\xa0B\xee\x9c^V|z=\xda%\xf2l\t\x83w\xae.FuYs\xf3zC\xb3\x91\xfc\x16}\x04\xbc\x83w%K\xf2@\x85\tD_)s\x85ܓ\xeacw\xd5\r\xaaf\x11Ood\xd6\x05\x955\xa4\xb7\x810j\x85\xe9V\xfbN\xda\rk\x9a\xe62\xbb\xb7\xeaȂ\xce\xe0\xf8X\x93Wo^[R\xb1Z\x87\x15\x19\x11\x12\xc1\r\xe6\"\xb1\x85\x92K\x96[\xd5\xe9=U\x8cN\xb85\x82\xa7\xa0@d\xa0ɗ'\xef/\xde\xfdt}\xf1\xe6\xf24\n\xb85\x9dᱠ\xc2\xd2`\xa9\x834\xafv\xdf.\x00Ē)),\x82\xe2\xb0q5%\x94,\xc3l\xb3*\x13͚Z|鵹(\x88Պ\x83#\x84\x89\xa24\xc1;\xfa\xc08'\x938\x88\xa5\xc8\xe6T\xcc,^_\xcb\xd2\xce\xf3\xcb/\x11+\n\xf22\xf3\a3\n\xa2?L_\x9e\xf9p\x16\xe5\\>h\x94-\xa03Zx\x1cG\xc1ll/\xd1+a\xe8\xe3K\xc2\xc60&G_6\xfet\x14\x05\x13\xb1U(i\x97\xe9\xe2\x11\x0e\x8b\x9c\x19P\x94\x93\xa3&不\xbf\xb4넼I\xa0\xf85\x01KP\xce\x0ep$\xb7\xaf\x03\xdf\r\x053\xaar\x0eZ[\x9e\xfb0\a3\a\xe5\xddJ\x9e\xc8 \xc6\xeb\xec\x86T\xf6|ufJֹ\x91Q\x10C\x1e\xe5}\x95\b7T\xdf\xebs&\xacH\x1d\xe5\xd4\xd0Q\x83\xe9\x9e;i8\xf2\xf2y\x14,\xe9Qu\x1c\xcf\u007f\xa3J!\x98\x98\x8dh\xf5\x14\x13#:\xd2s\xe0\xfc8b\x96Q\xe2\u008dh{\xb7\xf9ZL\x80!\xd21\xe1F\x9b\xa3_V\f\xdc}yL\xae\xa5ٕ\x81\xb6}T\"\fq<\xee\xe4\xf1\x97\xd7w\xef\xfe~\xf3\xf6\xea\xfa.\x96\xb57\xc5\xc2vV\x9f\xc6$[b\xa1\x83\xd5\xc7\xed\xfe.\xb1\xd0f\xf5Qp\xb7\x88\x85\rV\x1f\x87\xd8\x0e\xb1\xb0\xc9\xea\xe3X\xf0\xa6X\xd8\xc2\xea\xa3\xc0\xae\x8b\x85\xad\xac>\nj[,lc\xf5Q \xbb\xc5B\a\xab\x8f\x17B\x9bb\xa1\xcd\xea\xe3 n\x17\vk\xac>\nl\xb7X\x18X}\xc7kq\xac\x1e\xc42\x99\xcd\u007f\xe7ͯ\x06+\xaa\xf6<\x8e\x0e\x8dČ\x03&\xda|\xaeK+x^̷]\x82b\xf9\x9e\xb6\xd3*Ds\xb1Q\x90I}\x1cB\xc66\x8a\xb5ʢ\x8dc1)V\x9a\x1bOEκ\xc7f<\xcdߚH\xc7\ai\xe0dL\xde\xf8\f\x03J^\xfdt\xf5\xfa\xf2\xfa\xee\xea\xeb\xab\xcbwqH!\xe9g\x87\x84\xa4\x91\x9e\xa89\xee0\x0f\x13\xf0\xb2[s\x88\x16\xc8n\x14\n\x96L\x96\x9a\xaf\xaa\xf4\xf6\xfeG\u05cd\xf5\x93\xebS\xcaVD\x83Z\xb2,e\xb6\x9dS\xeb\xa3\xea\xb8\xf1\xa4\u0093\xbe\xfa'Ԟ\x04\xc0\xdbmb\xaf\xfc\xa4\x90\xd6!-c\x0f\xf2\x19\xecc7\x9e\xb0\x92\x13 \x1eV\x81j\xccr\xa7\x1a\x95\x00t\xb7\x8dM\xf6N\\l\x0eT\xbf^Ô\x96\xdcyێ\x8e\xc61\xba\x8c\x1b}Y\xec\xd7J\xee\x19@i\x8e\x16\x9b\xbdu\x97\xbcB\xc4\xe00B\xe8\xd8'ƶ\xd4\x0e\x1di\xaf\xba\xc1|\xeed\xb0)\xa3\xf2\xe6\xea\x91.\xe5\x89\vIO\xd9\xec\r-\xbe\x85\xd5;\x98\xa6\x80XG;\xe6\xcc\xfa\xf4\xd2XӠ\x1e\xa8\xf5\xb8\xa9\xa5pžx!1\x19\xc5]\xa3\x85\x93;\x9f\xfd\x8c:\xacEOڒH\xbf\x83\x15F\x9av\x17F[\x95i\xa8y\xc9\x10+\u007f\x88\xd9\xd7pˤȠ0\xfa\\.\xad\xee\x00\x0f\xe7\x0fR\xdd[K쁙\xf9\xc8\xc5\xc3\xf49^\xc39\xff\r\xfeO\x8f\xd9ݽ}\xfd\xf6%\xb9\xc8s\"\x91Ֆ\x1a\xa6%wiw{g\xfav\x8d\xba\xa8\xc0\x19^l?#%\xcb\xff\x1c\xcfl\xc38\x00m\xc8\xc2eb\x1e\x88>n1\x92\xbf\nR\xaa\a\xae,\v\xaf8\x02\x91\n\xc3o\xfb\xa4\xc1n\x1f!a\xd9+\xba=\xd1>\x91\x92\x03]/\xe2\xb0\xdf\xd8?4\xdc5\xf6K\a\xee\x1a\x11\xe1㮁'\xe00R\xe3\xb8\x16\x1b\xfb\xa5\xb3v\x0fop\x162\u007fItY\x14R\x19]\x15,\x18[F\x10\x17ϨG\v\b\xde\xed;#\xffY\xfd\x88wG\xf4\x0f\xc7\xc7\u007f\xfa\xf6\xf2\xef\xff\xe7\xf8\xf8\xc7\xffL\xfdN\r\xb3Qk\xe6\x10\x80u\x01\xd9X\xc8\x1c,\xcb>s\xff\xf4\x96\xd7E\x86\t2\xd7=У\r5\xa5\x1eϥ6W7gៅ̯nz\x82D\x18:A\x05%\aQ\x02\xb6\x15~\x89\x19-J\x0f\x05bz\vM_K\xc6\xd2\xfb\xd7\xf6\xc8\xdcP3\xdf?Ůk<(f\f\b\xb4UA-4\x91\xd33\xcb\x1d\xd1\x14\xe8û%9Z\xbe\x88\x8cP\xb6\x00\xf4\x17lӀ\xa2\x03m#b۳\x9b>\x1c\x8b\x04צe\u007f\xc1KPeS\xf6\x00zqs\x15\n\x0f}D\xc4\xf7\x95lն}\f\xf9\x16\x12ο~\x169\x17\xa0\xf7\x13uuN\xb1\xbb\x83\xb1\xdfM\xde\xed\x833\xacPDE^W):q?\x8e\xb3\xa2Le\xe6\x1e\xc2\x02\x16R\xad\xce\xc2?\xa1\x98\xc3\x02\x14\xe5#m\xa4\xa2\xb3d\xf1\x13\xa6\x8aS\xac\xff\xe5>\x97\xca\xf9\x1b(\u061ci\\\x12O\x03\xaa\x02\x92\x95\xcaZ;|\x15t\x14\xc8?\x9a|\xab觻DҾ\xa3M\xe4u\xb2z?[\xb3\xe6\x1f\xe8\xc6YJ^.@\x9fUVJ\x0f\xc0\xe8\xd2\x14K\xb2\xa4J\u007fT\x8b+gK\xa6\xf7M\x97\xee\x1aT\xac\xde&\xb2&\x82<\xd6-\x82\t\x03\xb3\x1e&\xda\xe8\x10\xc8\xe84\x1f}\xf9\x88\x1e\x9b-KS\x94\x98<\xbc\xa0\xa6\x8aJ=\x162\xcds\x17F\xa3\xa0O\xdet\x98\xbeHqc\xbbQPc@\x89\x97\xe4?N\xfe\xf1۟G\xa7\u007f>9\xf9\xe1\xabѿ\xff\xf8ۓ\u007f\x8c\xf1?\xfe\xe5\xf4ϧ?\x87\u007f\xfc\xf6\xf4\xf4\xe4\xe4\x87o\xdf|sws\xf9#;\xfd\xf9\aQ.\xeeݿ~>\xf9\x01.\u007f\xdc\x13\xc8\xe9響L\x9e\xf2\xe3\xa8\xf6Ќ\x980#\xa9F\x8e\b\x9e,\xf6\xb0k\x04\xe4\x1e\x8a'\xbd\v\x9aH_\xc1K\x9a\x1a\xdbGd\x1d}U\xab^h\xe8\xa9Yi\xc8\x14\x98O\xcf\xe7\xec\xe6\x15\xd4pw\x8b\xa92\xf8\u007f1n\xe8\xfe\xa6\xa7CSm\xb7`\xb1C\x82\x01\xfa\x1e`1\xb4\xbf\xc4:\x12\xfe\v\xf7\x90\x10\x11\tcp\x95\x0f\xae\xf2m\xe3\x97\xee*\xbfu\xe7\xa7\xf6\x93\xa3\xb7\xbb\xdf\xd9\x1c\xfc\xe4I\xd2.\xf9\xe5\xb4պ\x9a\xdcQ\xaf$\xce01\x9706\xb4ߙOX\x17\x92#\x85,JN\xf7\xbe\x1d[\xcdc3sh3\xb90\n\xa6\x17\xafua\xd0:/ݥ\"D\x1f\xc1\xcd\\7r\xc19a\xc2\tI\xfc\xd8\x03\xe3qv0\xa659\xaf\x03\xa1._qi\xd1\xf00\a\x91t\xb7\xd2\r\xa6\x896T\x19&fc\xf2\xbd\x85\xe5\xb41\x9f\x8b\xc2\x04Y\x94ܰ\"2!\xa9\xb2\xb0\xaa\xda$\x84j-3F\x8d\xc7p\xb4@\xe5T\x9b\xb0%\x98\x96c\xe8=f\\f\x90\x83\xc8\x00kY\x95\x91r0\xec\xf9de1z)\x96nn\x94\xe4\xa5K)\x86h\xee\xd3=\xb7\x8f\x9d\xeej\x8f\xafO\xad\xa9\xb3^#\x99\"\xfa\xb8\x1d\f9\xadK\x89U\xf1\xdd8x\xe9*v\x95\xfd\x92d\x86l\xe8\xd6u|\xbaҌS\xa2\xaaJ.>p\x16P\xba\x9a\xbbUŭ\x15\xd5D}\xe1SSo\x9fE\xb5=\xa4Z\xdbS\xa5\xed\xa7\xce\xeeRe{X<\xf5\x89:D\xb2F?\x05\xb4\x87\x12X(\x98\xb2Ǟ\x1c\xe6BT{DX\x0e°)K\xb2\x13\xacΤ\xa0\x00\x81i\xc2@\xb3\xb9+\x83)\xdaI6)4\xfd\td\xe8;\xcf\xc1a\x18\xfa횟c\xe0\xe6\x037\xdf1\x06n\xbe{\xf8\xe3\xf4\x19\xb3\xf2\x0fh)\xe3\xcd\xe5\xf4\xebկ\x1b\xf7\x9f\x91#<\xc7]\xf9\xea\xbcօU\xce\xf1\x8bq\xc7\x12\x8b\xc0\xe2ѳVd%\xe4\\1}\xf9@\xe6l\x16\xeb\x11\xe3\xb0\x04\xee\xf5{\xb2\xa0\x82\xce\\)M#C\xa8.\xf6v\x84eI\x8a\xe5\xad\xc2k\xb8T+8-\x9b\xe2\x92\xc6\xd1r\xdd;N\x13\xce\ue07c\x86\x82˕\xaf\x98)rrk\xa8\xb1l\xe9\x16L\\\x02\\\x12\xf3\xc0\xd5ܔ\x9c\xdfHβ\xa8\x98C\x9b\xf4\xae\x90抒sR \xa81y+ 6,s\xc1\x1f\xe8J\x9f\x91kX\x82:#W\xd3kin\x9c\xb9Y\xdfO\x89;\xbc\xd2\x03%lJ^\xba\xfeh\xc4\xd0\x19\xba.\xaa\xfauqD\xa1Z\x13s\xc2\xe4\x81\xe9\xbevz\xb4\xc0\xdc8\x80\xbf\xc1\xafZ\xd1\xe9\xfe\xfd\xec\xe4\xc3\xd9\x14\xb2U\xc6\xd3y\xd6E\x86ɮu\xf9\xf5\xfa\xdcƹ\x8cV\xda\xc0\"\x94\rC\a\n\xc32\x93\x85\x14\x1a\\A\xbd\x14\x0fW\xb5B\xe70\xd3=\xf78U\xc9+\xa46\xb7\x86\xaa=˴գ}Jo\x02\x18K\xfe\x19\xe5\x1cr\xc2\x16\v\xc8\x195\xc0\xe3\xfd\xe4\xa1\x02h\xb3ܣkw\xe9\x8aI&\xe9\rs*r\x0e\n\xeb\x15z\x1f`\v\xbe\x01\xb5`\x82\xc6\x16\f!Uz\x17\xba,!'4ˤ\xca}-\xb8Pً\xaax\x8d\xbf\xe2x\xa8+5$\xcfz\xbe^4\xe4\t\x97ٽ&\xa50\x8c\xd7\xe5!CmHߨ1\x1aj\x12\x8b\xa9\xfesT\x9d\x89\x11\xf6#;\xffM\xfd'\xfc!V\xf9\xedc\xf9\xecW\xcfws\xacՠ\x04$\rL\xa6\x94\xf1b+\f\xcc\v\x96V}\xb1DU\xd7W\xad\x04M\x9a\x91\x81\x05\x88\xdb]u(\xb2M\xac\x8bF\xef#\xab\x90\xb8\xd17G!\xa1\x16Ps\xec([\x9c\x1ck\f\x85m9\x13Ь_̰&jz\b\xb3y\x82\x1d?\xf2\x16jz\x10\x98)\xec1\xb2jԶts\xef\x93̯\xa44\xe4\xe4\xf8\xfc\xf8t#\xa8u\x9c\x0eu\xca88\xe9\xea\x8a,e\xd5f%\x83\xd4lQ\xf0\x15\xee\xcfq\x8e\x1d\x9d\xfcuXU\xa6ň\t25\xbbˡ \xd4\x19ђ\x18EC\x97\x81\xf4\xb9Zh\x16\xb8Q\xa5\xd7UN\x8e\u007f>>#`\xb2\xd4|`B\x1e\xa486HFcr'I\xa9\xeb\x89'\xc3\\ɒ\bpu\x00\xe0\xb1\xe0,c\x86\xafP\xcc'Ô\xa5q\xc5\x17\xb1A\"\x16ں|d\xc6\xdf\xd3I\a;%_\xe1iw\xaa\x02\xa1\xd6\x18Z\xc2\xf9\x1c(7\xf3\xf4\xfb}\x96.\x85\x14\xa3\xff\x06%\xb1\x8c\x97\xf0\x10S\xbd;\t\xb1\xb3\xe68@\xc6I\x8a\x1ba\xfd\xed\xc4$\x06\xab |\x03\xd1*'\xd9\xe8Hzww\xf3\r\x98\xb6\bKB\x87\x9dQ\xc8\xcfG\x976\xa8\xa9T\x1d-w\x9f\x1e}\xe5\xdf\\\xea$̐\xcd~\xadڸ\xee\x13\xceH\x11i>g7\x8cl\xa7%\xfb\x8cFru\x93\x9e\x88\xf5wYZlM脯\xaa*\xb2\x1a\f9\xb2SOO{f\x02\xf7\xf3\xaf@s\xac\xdb+\xb4\x01\x9a\xa8\"\x1d\xe0\xa85\xe6r\x18\xa5\xc6\xf5ݝ;\x90=v\xb4Y\x02\xcb\xd3\xfe\x18\xcfT:\x9bt\x15^\x14\x14\x8e\xfd\xfa9~$&\xb9\xc1+\xdc.\xf8\xdf'\xbdr\x13ih\u007f\xec\x96\xe8k;'\x16\xef\b\x83\t\x9c&\x1e\x8a\x1e\xb3\xeb\x9f%Lzg\xab\x92\xae\b\x98\xc3U/\x98\xfe\xeee|Z\xda\xfa8\xc8\xfd\x92\xe4\x12^\xcd\xf1\x9ch\xc2\xe9}|<\xf5K\xb5$i\x89\x88\xed\xd7\xfba\xa2\xe7\r\x05\xd2[\xdf\xc2\xcb<\xc9\u05cd7/\x1b\x1bIh\x96\xa5\x15\x8ar\xc3w/G\x86\xa5A-c\x13\x1c\xebћ\xc4\n\x19\xef\xbf\f\xa3ׅ\xb7\xc3\\w;\xc8e\xb7\x8ez\x89\x8a\x88r1\xe9\xc1I\xaa\x02\x18\xca\xd4\x04\xe37\xbe\x873\xa5*\xb6y\x8d\xd3\v!\xdc>\xfa\x1e\xaa0T̀\xbc\xb03\xfd\xe3\x1f\xfe\xf0\xfb?\x8c\x11\r\xc9PC`\x99\nruq}\xf1\xd3\xed\xfbWX\xc4-\x95ʟ\xe5f\x1b\x96mH\x96?\xed\xc8<\x82\xb2\xd8+5\x16:\xeb\xb3\xc3\xd6\xd6\xf0\xfeo\xe7\\֩q\xb6\xe60\x12\xd9\xcdG\xe23}\x84\xd8\b\x0fч\xb6\xb3MV\xdc\xca\xec\xfe\x00\x96\xf6\xf1ݫ\x1b\a\xaa6\xb6\x93v\x81\x8a\xe0bfb)\xf9\xd2\xf5\v\xbc{u\x83\bJ\xdbY\xfb6\xc6\a\xd0շ\xb2s\f7\xe1]jN\x12T\xb6(|\xc7LJ\x14Pδa\x19~\xab\nS$\xda\xf7\xf2>%\x8b\xe7\x93\xf1+\x1c\xbf\r\xe9@\xe8bH>\xcdk\xae\x89\x96\x8b\xa1\x0f\x8bh\xb8&R\xaft\r\x1a\xc9\xc15\x12'\xea\xa5\xea\xa7\xc7\x0f\x1aɧ\xad\x91|n22\xf9\xd5B\xc1\xad\x91EϬ\t\a\xe4@9\x13\xa1\x13ݶ\xa4\x06\x92'l\xa9\xeb\x1d}qsUy\xc7e+\x11\x01\x93W\xa2\xa1\xea2\x9b\x87،\x00\xad\xcf1=\xa2,\x9c\xe7+4\x94\x8c\x8fX\x15\n\xb0\v\x9f\x14gUE\x02D\a\b\xf7#\x98,\xfe\xb4\xa0O\xc6\xe7\x8e\xf8xbخ\xbei\x18\x99\xa2z\x0eة\x02\x1e\x99ѡ\xdb5\xd5R\xb8\x10\xae\xdf>&\xe3\x03\x98L\x93\x82j\xed\x02w\xa6^\x84\xfbȍ̏\x13\xa2\xb7\x8d\t\x91\x99\xa2\x19\x90\x02\x14\x939\xc1\xaa\u007f\xb9|\x88\x9f\xe7\x04fL\xe8@\xbfv\xa2\xe1`X]\t\x92\"\xc2u\xe7\xd9w\xad.Rخ\xbc4\x99L\xe0\xc3\xfeu\x8f\xc5\xf5\x04\xa2諓8M{|J\xca\xf9\xaa>\xa8ᦧ9\xfc&mf\x12\xa5\"\xa1^\xf7z&Q|4\xb0\x95yd\x8fB\x9d\x95ԇ\xfc[\xd4ɴ=UټG\x9b/\x12\x9f\xbe<\xa46=9\x86Ԧ\xbdǐ\xda4\xa46\r\xa9MCjӐڴ\x17\x88!\xb5\xa9\x9aѐڴc\f\xa9MCj\xd3\xd3cHm\x1aR\x9b\xea1\xa46\xed5\x86Ԧ=Ɛ\xda4\xa46m\x1dC qHm\xfa5\x06\x12\x87Ԧ\xb8ׇԦ\x881\xa46\r\xa9Ma\f\xa9M\x91c\xd0H\x86Ԧ_\xa3F\xf2\xb9\xc9\xc8^\xd5\xc5\"_\vy<7JNz\x94\x19\xbb\xc1X=\xcb|\x1a\x90\x9c&\xd7\xd6q\xd3\x19\x93W\xad\xf4\f߄\xdfUi\x89\x82\xe8\x13}\xea\xf4\xa4\xbe\xf5z\xa2k2\x85\xa2`\xfa\xbc\x90\xee\xff\xd59\x05\x8dd\x02\xe7_\x8b\x11\x0e\xa9\xc27%\x8b\xe0\xa9\f\x82$^\xb7;{\x003\x01\xa2a\x1e2s\xa0\x8fv\xd3#c`G\xb6@\x00\x9b\xc4\\\xbb3\x05\xd6\"\xfeɩ >K`3\xda\xdf'\xe1\x02S\xe16\"\xfd\x89\x10\xab\xec\x80mQ\xfe4\x95\\\x1f>\xc2\xff\f\xd1\xfd\xc3G\xf6wD\xf5\xc9J\x96I0\xb7D\xf4}d>\x916;\xa3\xf9!*\x9f\x06\xb3;\x92ߊȧ\x12S\xaf(~\x8f\xe0TO\xe5:ݓ\x9c\xac)\xf9d㻹\x02=\x97<\x9a\u05f6\xf8\xec\x1b&آ\\X6\xa1-{d\xcb*\x9b9\x9eFB\x9e\x93\xd3:\\\x18\xce\x02f9`\x13K\xcaxJ\xa9:,\xad7\xa7\xe8\x9f\xd0e\x96\x01\xe4VN\xbe\xaeC\xe0\xd10\u007f?\xaeV\xee\xbaj0M^\xc4R\x9ek\xa8\x88\xf6\xdd\xef\u007f\x97\xb4\xfb)\x96ab\xc2\xc6\xd3\xc9\x1a\b9\x1a\x93\xfd\x135\xfa\xa8\x1b\xa9\x8e\x94\xe7I\xceؑ\x98A\xfe\x9e(\x1av$e\x10\x96&f\x0f\x94\x90ыs\xf6L\xc4ؑ\x84\xe1q\x94\xa8\x80l&`\xac'R\xa4\xa1<=\xf9\xa2\x87l{\xae\xa4\x8b\xed\t\x17\xa9$Iz'[\xf4O\xb48`\xb7\xc3:s\xa0ww\xfc^.\xba\x03x\x0e{&U<\x17Z\x0e\x91B\xf0\x11\xbb\xcf&\xefj\x9f䉞\x89\x13}\x92&R\x13&v$K\xf4\xf14\xf7L\x94\xe8E>\xa9\xe1\x88\xe4PD\xff0D\xef\x10Ď\x84\x88>=a;C\x0f\xa9\xfd\v\xc3h\x87\x1d\xd6\xc2\a\x89ja3\xe4p\xd0\xd0\xc1\xc1\xc3\x06\xe9I\f\xbb\x13\x18\x1a\x89\b\xa98\xdcL^蓄Ѓ\xa2S\x99\u007fRP%\x99i3\xc1\f\xa3\xfc5p\xba\xba\x85L\x8a\x13\xa2u\x1bsN}\xe7L\xc8Å\xda\x10\r\x89g\xad\xa8>\x12\x8aq\n\xbbzӾ=\xf9q\xe3\x16䣹\fܕ\xd2C\x10\xc1_\xe5\x03\x91S\x03\x82\x9c0\x11\xe8 ޏZ;\vj\u007fQu\xac\xed__|\x15Ϲ\xdcd>_\xc7\x0e\xba\xb6\xb4~>\xbf\x9e\xff\xc0\xe1\x1d{\x1e\xf0\xb4\x8c\xf7ѷ\x9c{\xceA\xd8\xe6\xefћW\xb7\xe1{\x81\xf3\x0e\xdc\x04\xbdԾlC\x02\xccϔ\xa8\x92\xd3ΞL9#\t\x9d\xc7v\xa5\x9bթc\xd1`\xb7\xa4\x9a\xd5ic\xf1\x13ݖf\x96\x942\xf6\xd1=\x9ckib\xe9\xe6\xe7\x96\x141\xaf\x9e%*\xf1\xc9\xe9a\x83\x1d\x169v\xa4\x81\rv\xd8'd\x87}\x1e\x16F\xa3\xd6\xc97\x8afps053\xb0+\x92\x97\x8az\x91\x11\x14\xbc${\xc32\x19\x01\x90;NU\x15\xae\xc1\x8a+Ӓ'\x14\xaf*\v)\xda՟\\NE\xb3\x88K4P\x9f\xedұj\xaf(\xa5\x9c\xd0BI\xa7\xf6\x11U\na\xa5\xae?K\x16)\xd6V\xd2i\x12\xb2Y\xb3G\xb3\x99\xdd.\xabba\x15\x1c\x96 _\x1e\xe6 \x82\x96\xe9'lg7\x95*c\x13\xbe\"s\xcaS\xc2/\x0f\xcc\xcc\t%\xf7\x8cs?\xcd1\xb9\x05C̜\xe9Dg*\x97b\x86\x9bA݄᱀̪\x1d\x19\a*\xca\"m\xfdVY]\xc9R\x85\xf5\xfb\xb6qa\x96)I\x1b\x82\xf1\xb3\xb0\xd5\xc7z\xf7\x81M@\xacKP,5\x84:M\x0fL\xc3Y\x1f̆6\xa3\xee\x1c\xb8u\x17J.Y\x0e9\x99\xac\xd2\xe8_樵\x8e\xc9{\x84\x17\xf8\xbe\x90b$`F\xadm\x14\u007fR\x9d\x10wg\xde\xcd\xd3գ\x109˨I\xb0\xb14\x16֫\xcb\xe9\x91%\xa3\x88\x85\x06\xe5F\x03=\x11\x92HT\x8aK\xc1\xcc\nc\xa3\xf3Ґ\\>\x88\xd31\xb6\x9eMaR\x94L\xc0P\u007f\xafյ\x12D\x81\xa5\t\b:\xe1)\xca\tf\xe2\xdeu\x12(\x99\x025eBw\xbf\x195\xd0\xe9\x0fp\xf4p\xd8\xe3\xc0\xb4\x8f\x80NI)4Dߟi؇\u007f\xfc\xd7\x0fg\x1f\xb2\x05\xc8\xd2|R\x0e\u00879\xcb\xe6M\u007f\x03[\x80&\xb2\xecsm\xcdH\xf2\xc2O\xab\x9b\"\x9e\xb9}\xe4/Ϋ\x98\xa45Ɔ\xd8;\xe2F\xeb\xd5\xfc\xaa\xc4\xe9\xa8uS\xcb\xc3^_\xdf\xfe\xf4\xdd\xc5_.\xbf\x1b\x93K\x9a͛eH\x05\xa1VnD\xc1D\xb92\xa7K \x94\x94\x82\xfd\xb3t\x9d\xc7\xc9I\xf5\x9dӐ\x83\x1f\x057-_?\xc9R\xb4\x82\"\x8a\t\xb46\xe8;\xa6\xb1\xd1+B\xf1\xe9\xacR\x03\x99*\xb9\x88cJ-\xeb\x91\\Z0\xce[\x84\x96\xe6\x1c\x14\x90\x19[F\nY\v\xd57G\xa6yH*\xc6#lO\x8f\xd5b\xe9D\x96\x91&\xd0\x1c\x88\x00cOw\x15\xe1\x92B\xb7jږ\x1at\\~\xf9\xa4\xc4T\xeaB\xb1\x05U\x8c\xaf\x9a\x93\xb4\xea\xeb\xb5\f~\xb8U\xac\xa8m\xa2\xf0\xf5\xdb\xcb[r\xfd\xf6\x8e\x14\n\xcbz\xba\x9c\xe1h\v\xd2n/\x99\x80\xdd \xb7\xe1\xf9\x98\\\x88\x95\xfb\x90\xe3\xe5\x91Z\x06g\xda\x00Z*ޕ\x10\x9a\xd6\x1f}5\xc6\xff;\xb2;\xa8bCDUzy\xb6q\xc9\xc6y.\xd8$\xf2\x1e).\xbdA\x03=\xef\xd8$\xa4z\xad]\x9a\xf0뺱\xa8WP\xb8\xbe\xec\xb1ҒV$\x8d[\x88\xccО?\x9e\xec\xd3Iw\x80f\xcd%\xc5{\xdd:\x1d^\xd3\xcaa\xe5\xe85\xc1\xdf#Eì\xba\xba\t\xe4\xe84j\x94\x04\t@-\x1dZ\x9d\x84\xe5n\x82.A\xe2\x8c|E\xfeD\x1eɟ\x12 \xfe\xf1\x0f\u007f\xf8\xfd\x1f\xe3\xfdY}\xf4\x89>ʨ\xf3v_\xdd\xf4\xdc\xe7\xef-\x1b\xb3\x90\xec\xce\x18I&,鎋\xb3\xec\r(+&<\xc5\xc4㲇\xc7\xd6.\xe1\x93${\x97\x85q5\xad\x95/g\xf4'@\xac\x9c\xb0[\b?\xc5\x17K\xfe\xe4\t\xdfN\xf1\xafR\x9bk\xcfΘn\xcc8\x89\"\xfc\xe1&\vj\xb2y\x9b\xdfZ\x13\"\xe9\xd8\xd7\xe5\x97I.1\x96\xe5\xae\x03\xcdYB\xbe\xf0\xc7;\xbai\xe9\xb3-Jݤ\xa8>\xactͭ\x8f~\n\xaf\x97\xbb\x82\xe5\x89<\xa1\x90\xb97\x18\xec\x92\U000c640c\xb5\x18\xdc\xd8b7\xf8(EZ\xf1\x97\xfab\xbe\xe5\x85\x19\x15\xee&\xf1\x14\x94\u009bf)(]a\xc6$\xcb \x81,{p\xc1BI#3\xc9Sh\v\xb5Ɨ\xe4\xeeU|\x19\xc5v機\x03\xfah]\xb4\xfaM2a\xfe\xed\xf5͙\x9d\xd2\x19\x91\x8aܾ\xba\xbb\xe9w\x95\x89\x90\xa3\xbbW7G\x1fpOҢS\xa3\xb6.\x17\xf9n\xa0\x828\xeb\xacOE\x81\xd8D\xe7V\b\xd0Z0\xa3\x05-F\xf7\xb0\x8a\xd2yӱ\x94\x84\xa3\xcdI\xbb\xc5/\xe8\xfe7\xc1\x14М}B\xc5\x14<\x97\xaa\xe7\xd5]Ua!\x97\x91N#\xb4\xf6\x02t\x10y!\x990\xba\xab\xd4B\x14\xd8M\x93\xf1\x93IY\x1cJ-t\x8c\xa1\xd4\xc2\xd61\x94Z\x18J-\f\xa5\x16\x86R\v\xddc(\xb50\x94Z\xf8\xac\x92\xa7\x87R\v\x8d1\x94ZH\x18C\xa9\x85mc(\xb5\xb0\xd7\x18J-l\x8e\xa1\xd4B\xe7\x18J-t\x8c\xa1\xd4¾c(\xb5P\x8d_\xce\x15\x9f\xa1\xd4§z\xc5g(\xb5\xb0\xcf\xf8<.B\r\xa5\x16\x86R\v\x01/C\xa9\x85\xa81\x94ZX\x1bC\xa9\x85ϕ\xa8\x86R\vC\xa9\x85\xa1\xd4B\xf7w\u007f\xedv\xd8Pj\xe1S\xb5\xc3>\x0f\vc(\xb50\x94Z\x18J-\f\xa5\x16\x86R\vC\xa9\x85\xa1\xd4\xc2Pja(\xb5\xf0+\xf2*&i\x8d\n\xb4,U\x16g\a\xb7\x89\xec\x95\\\x14\xa5\x01\xf2.\x80\xaa\x94娅\xa3,a\xbay\xa3\xff\xc3v\"̤\x98\xb2\x99W\xf4\xce\x17T\xd0\x19\x8c*\xfc\x8c\xea\xfbw\xe7\x1f\"7\x9e\xb3\x05\x8b+\xb2`G]\xb1ই\x87#Ѡ\xeekN\xf74\xa6\vj\f(\xf1\x92\xfc\xc7\xc9?~\xfb\xf3\xe8\xf4\xcf''?|5\xfa\xf7\x1f\u007f{\xf2\x8f1\xfeǿ\x9c\xfe\xf9\xf4\xe7\xf0\x8fߞ\x9e\x9e\x9c\xfc\xf0\xed\x9bo\xeen.\u007fd\xa7?\xff \xcaŽ\xfb\xd7\xcf'?\xc0\xe5\x8f{\x029=\xfd\xf3\x97\xd1S=\xb0q\xda>\x8f\xdf!\xe5\xd4)Eȷ\x17\xf4\xd12\xd8xRX\xc8R\x18w\xcb\xc6\x1d\xf3\xeaD\xb84\xac\xd8CI>\x95\x83I\xfa\x18\xda>\x1fm8\x9f\x11c8\x9f\xee|\xbe\xf3\xb4\xd3>\xa1\xd1s\\x\x95i\xc7\t\x8d\x86\x19\x047\x1a\xba\xd5<\x99&r\xc1\x8c5\xa7S\xae\x197\n\xa9\xe0\x95\x94\xa6\x8b\xda\xf1\xaax-o\xeanS0ݼ\xa0Ѹ\x14.\x83훢\x96RQ\xc7)\x90\xe7\x8cr\x982\x01\xb9SO\u007f}\xfc.\xe95\rY\xa9\x98Y\xbd\x92\xc2\xc0c\x94c\xbf}^nۀ\x88ی\xf8C\x13&Dd\xe1\xae\x1d\xadU\bÛ\u007fq*+\x10U\n\xf4g\xb9:\x17`\x9cs\a\xcdp\xbcٳ6\xf9(\xf0\xc1\xf5\xe2\xa8)\xb6\xe4\xaeO)\xd7ь<]\x1a[E\xe6\x8d5\xdf{\xedb\x05\x85\xe4 \xa4\xf1\x1e\xbf\xa4\xd3 \xa7\b\x8d8\x9fB\xe3\xb2@K\xe2%)\x99\xb50f:\xe0\xfc\xa6\x9a9F\x98\xe2S>4\xac\x9bq^\x18W^\x86\xa4\xa0\xbf\x02\x9acM\x99\x82\x9a\xb9\xcbS]P}\x0f\xb9\xfb!QǮB\xb2v\xc6\xd5\xd2\xefV\x05$\xc7SQ\xb7vٿ\x18\xe7\x8d\xf7\xc6\xf6(\xefE\U000f70af\xdeIi\xbe\xaeʘ\xf4\"\xe4オԎ\x03E#e\x8ee\xbb\xed\xfcF\xb8\x89X\xb6\xa5Yi\xc5S_\x8a\x95\xf0\x81\x19\x84*Ņ\xfeF\xc92Z\x15\xd8Pֿ\xb9z\x8d\xfc\xb2\xf4\x192¨\x15\x96\xa6Ja\x12\xed3W\xd9c\u007f\xf39MI\xd96\x15{\b\xe1z\xf2\x86\xae\b\xe5Zz\xc31!\x18\xdc\xe5!!\xdeU\x93r3z\"\xcd|ݧ\x83\xeca\xf3;\xf1\x05\x8c\xea\x04\x9bʓi\x97\xd0Dž\x84`\xe9=hR(\xc8 \a\x91ES\xef\xc7I\x83@ʿ\x96²\x97^\xb4\u007f\x15\xf2\u007f\x9c˸\x9fU\x8f\x99Jަ\xa7\x98\xaf\x84̥Ԡ\\r\x98*!m\xe3\xbf-'\xc0\xc18G\t\x16\xb9\xa5\xc6y\xfe\u0602\xce\xe2O\x135\x95(4\x92\x80Х\x02\xef47$\x97\tf\x80\xaf#e\x97\xfe\xb7\xab\xd7\xe4+rb\xd7~\x8a\xe4?\xa5\x8c\xa7T}\xc1\xdb\x1fk܄M\xc3\x14-J\xe3u\x02\x81ƾr\xac\xfa\x8c\bIt\x99\xcd\x03NS\xbcC\xc1y\xe5oH\xe1\x15\xb6\x815}\x02\xac\xa9\xa7`\xfd\x9b\x06\xd5[\xae\xfe\xed\x03\xc8\xd5>n0˛ڻ\x86\f\x85,\xc0М\x1a\x9a\x12|+E\xa3:\xe2\xdaQH\xa1\xdd\xddG\x01I;\x1a\xe6\xaf\xec(|\x1c)\xad\xe1;&\xcaGw;\xa0\xbfC\xf9\xf6\x12\xc1\x11\x1fJJ\x91(\x13 \xb4(8s\xe5\xfb\xd6Z\xc4\\\xb5H7m\xef7MM\x14\x0f\x94siՌ\x84\xf0\xb8\xa2\"\x97\x8b\x8d\xc5[C\x14h\x82U\xdcXp\xc7\xe1\xdcv\xd8\xe2ew}8\u007fm\x87\xad\x8f\xeb\x9e\xc3\x12\x12\xaa\x94\xaf7Q\xb2P\xacA\x1a\xa8\x06\xc1&y?9\x9d\x00w\xaa\xa1;9z\xf3\xe4${E\x13\x9d\xaaJ\xf2\xfe%/\xdeI\x0e.7> ɂ\xfd\xc5\xe0\b_\xee\x8b#\xf4>\xb5p\x94\xecE\xff\x14qT&hxd\x1dGVMl\xe3Ȃ\xfd\x85\xe0(9\x04\xa1!\xcb䢸Qr\xca\xe2\x0f\xeb\x86\xe8\xf7\xe0\xea\xe4\x9cx\xd1_j\xe8\xca\"G=\x12\x81\xc7k\xe4~2T5.=Q\xe3d\x9e\xbf\xc5\x15\r\xf4\xffk\xa8\x10ȵ\xcf\xd6\xf4\n\xff\xd5\xf8\xd96\xf3\x85\n\x99\a@\x1fT\xbaɌr\xecH\x94F\x17d\x9d6\xd6\x01\xf6\xb8\xcfE\\c;\x0f'\xe4\xf4aK\x16\xfc%\xc13@Bs?\x99C\xa3v\xbc\xbb\x80w\xe7\xee\xcbX\xd8I\x80õ8\xab\xa7\x84\xe4\xab<Į\xec\x17Ӧ+}\xa9\xec7UO%\x8bp\x10yj%\xa8\x82\x9a\xf9\x19Q\xc0\xf1\xe2^`h\xf7Ρu\x9c\xb6O\x8d\x05\a\xce\x106\x0e\xf5l&E\xda%v\\5\x86\x05\x82F\x947\xe5{\a.\x98Ιew\x86\x89YB\nF\xedQ\xa1\x9c\xb72\xf4\x0e\xe1R\t\x9c\xa0ꓺ\xe9:H\xf6\xd9;bn\xfb\x12{\xfb\x0f\xb6\xb87jwE\xbc3e\x87{ù+\xa2A~\x1c\xf7\xc6l\xa1\xe9+e\xbfk\x18\xe5\xb7E|\x87\x1f\xb2N\xcb\u07fc\xb9\xbdh\x83L\xe3\xec\x98\u05eb\x9czla\x12\x9a/\x98\xd6L\n\xf2\x00\x93\xb9\x94\xf7IpOB\xea\xfc\x8c\x99y9\x19gr\xd1Ȣ\x1fi6\xd3\xe7\xfed\x8f,vҚ\x9c0\xc1í\a\xe7!\x14F\x87\x88\x81]L\x9a\x96Ua\x15\t\xd0w*\xf4\t\xae\x9bh\xbfN-R\x857\x16>\xb8J\xb5I\x8a\u05c9\x05ş \xc7d\xbc\xf8\xea2\x8djO\x8e0\xeb}I\x13\xb7v/]\xe8\xe7÷\x11p\xa6Z\x06\xba\u007f\x1b\x81\xbfְH\x0e\xae8D\xa2\xddǦ\xad\x86\u07b5B\xe2\"ډ\xb6\xe41\xd6n\xf3S\xe5\xa2\x1f\x91\x1a\xb0o?\x8f%ی\f\xf16\x92\xb3\xe9\x14\xc2\r\xe7H\xb1WPE\x17\xd6p\xd0ħ\xfeN`\xc6\xdc5\xd3J\xb5\x8a\x8cPTE\xc2Μ\xba\xc7\fY\xb0\xd9\xdcyi\b\xc5R\x94\xf1\xe5&\x8d$\\Ҝ \x17\x97\x8a=4\x9f\xde{\fͧ\x87\xe6\xd3C\xf3\xe9\xd814\x9f\x1e\x9aO\xef=\x86\xe6\xd3C\xf3\xe9\xa1\xf9\xb4\x1bC\xf3\xe9\x8414\x9f\xde6\x86\xe6\xd3{\x8d\xa1\xf9\xf4\xe6\x18\x9aOw\x8e\xa1\xf9t\xc7\x18\x9aO\xef;\x86\xe6\xd3\xd5\xf8\xe54=\x1b\x9aO\u007f\xaaMφ\xe6\xd3\xfb\x8cϣ5\xdc\xd0|zh>\x1d\xf024\x9f\x8e\x1aC\xf3\xe9\xb514\x9f\xfe\\\x89jh>=4\x9f\x1e\x9aOw\u007f\xf7\xd7n\x87\rͧ?U;\xec\xf3\xb00\x86\xe6\xd3C\xf3\xe9\xa1\xf9\xf4\xd0|zh>=4\x9f\x1e\x9aO\x0fͧ\x87\xe6ӿ\"\xafb\xe2M\x91\x9cE\xb5lۣ[@J\xed\x93P\xbb\xd32\xb2r:\x05\x85\xc2\x17g\x17\x94\xa3\xb4K`\xa13T%\xba}F,6\nT@sW\xf3\"\xce/\xd89\xadP\x84\x14ۗ\xb9{\xa9\x91\xe1\x01r\xf9\xf6\xeb\xda\xe9\x9a\xd2\xea \xedv \xae\xe7\xad\xc8\xd2\xef\nՄ\xd0Q\x9d5\x0e\xb7.\x01?\xe3R\xfb{\xb2\x88\xeclN\x85\x00\xee\x95n\x16\x87\xd99\xd5d\x02 \x88,@8\xb5\x85\x12\xcdČ\x03\xa1\xc6\xd0l>\xb6+\x88\xf3\x9ey\"\xf0]\xeb\xea\x99j\xa3\x80.\x1c1(X\xc4\xf6\x19\xb4S$4SRk\xb2(\xb9aE5I\xa2\x01KeD&-]M\xeb\r\xc6$\xf1\xfa\x02\xeaY\xb5\x8a\xe89\xba2h\x8d3o\xa82g\xd8\x0evQ\x98\x95\xbbK\x15'\xf8\xb0k\xa7҆d\x9c\x810~ծ>#\xce\xf3\x8c\xc4\xe6\xc6\xe3\xf5]\xb7\vڣV\xe4\xe8\x15)\x8cv7}\xd2&꧘3\xed\xbdo\xfa\x8cP\x13\x04e4\xd1\aZB\xb2\x0f\n\x9c\x9b\xb5\xff)q\x9auI\u007f]_5\xab\x99\xe1\x94\xd38\xc500\xa5\xb3V-\x87\xda>\xc4$wd\xabQ`\xb1\xec\x90\xc3\x02\x1e\x1c\x01K\xcb? \x03\xb6D\u007f\x90\xe5\x8cQ\x10\u05f9\xe8\xb33ц\xee\xfa\x06\xb4\xa63\xb8\x89L\xb1\xd9\xe6 \xc6,\x9b\x9a\xb8\"\r.\xacFfdC\x87\xab/\xa0\xb4-\xd0(\xb0\v\xb7\xc6\xca\xe6|P\xcc\x18@\"\xc6\xceU\x98y\x18\x99\a\xbe1\xb9\xe6\xf5\x987\xe1\x83\xeeC\xb1Tk\xf5)\x91\xbbK\x1d\x13 \x13\xc5`J\xa6LP\xee\xefa\xc4]8\xc2~\x16T[ҤZ\x83B\x9f\x8bw;\x05\xdc\xc4\x11\xec\xf7\x1e\x91F\x95\"\xa3\x8d.\x97X\xfd\x8eM\xc9\f\xefzD\x1a\x13s*ȿ~\xf5\xef\u007f$\x93\x95Ղ\xd186\xd2P^m \a1\x8b\xac\xed\xef\xc5S\xbb\x0eYE\t\x9c-X\xac[\xc8\x1a\x03\xbf\xbb\x9f\xb4\x03\x8d\xe79,\xcf\x1b\xf49\xe2r\x16\x87\xd3W\xe1~eug2F\x91Or\xedw\xb0\x01\xc9Y\xb6Jf\x04\xa1y\x0e\x99\xcb\a\xe7\xca\xebyb\xeb+\x8e\x85,J\xeeR2\xbe\x0e\x95%\xa3@\x96\x1a6\xabau\xf2\xc1Xj\bS[\xef\x10\xee\xaeL\xf9\xa5\xc4)-\xbe\xf0\x9c\x0f\x8dW=s\xd0O\xfc5\xe5|B\xb3\xfb;\xf9\x9d\x9c\xe9\xb7\xe2R\xa9\xc86\xfbH\xfd\x01\x1f\x9cZ-f^\x8a{ly[\xd7\x1a\x96q\xd2V\x96\xa6(M\xb8\xe4\xddt\xef\x86͌\xae\aY)h\xc13\\\xcf\x0e\x1e\xed\xb9E\xf7l\x1c;\xf0\xc5w\x1cw\xe1rV\xcd[\af\x10{#\xe8w_\xfd\xeb\xbf9\x96E\xa4\"\xff\xf6\x15^\x19\xd5gN\x88\xa1n`\x15\xd9\x05\xe5<6\x98\xd5d0\x96\xe8\xc7\x1dL\xe2\xd9y\x84Ig\a\xcfbr\xdf\xdd\xfd\x1d\xedmf4\xf0陫=\x12<\x88Q@\x8fQ\x89;\xf6R\x16\x8b\xdc|\x04\x83v)y\xb9\x80װdY\\\x84\xbf\x85\xea\x16\x94\x10\t\xe2L\x1b\"\xe3\xaa@L\xb8\xcc\xeeI\xee\x015\xeef\xac\xf7\xb1\x8e\xc1L\xc2-\x94\xad\xab\xab\uf7d0\xd8fD\vZ\x14U-\aE\x1fZ\x8bE^\x12}\x01\x85\xa6\x06\xaaӳ:\xdctc\x15\xf6\xf0n\x03\xab5\xa0@0E\xac\xf4s\xc3\u07fc\xdehH\x15:\xe8%\xe5\x1a\xf8=qz\x9a\xdd9\xe4\xcc\xf1\xe1\xf5\x1eI\x0fiwzZ8\x16U\xae\xc0\x82\x1ao\xd3$\xe6\xcf \xd5\x16\xa04\xd3V\x81y\x8fg\xe2\x15\xa7l\x91~\xc3?\xa5!A\x8f\x16\xb0)y\t\xa3\x06\x9dF\xbe\x18\x8d\xe8^u\x8f\xe2\xee\xb68\x96\x86-}ӹ\xfe\x8d\xcc= dծ\r\xb35e\xa3\xc9a[\xa1\x87^\nG_\xb6\xff\xbe\xc6Q\x93\xeb\xbbu\xc6\x1fg<@\x0e\xa6g\xf6\x1f\x83}\xe3\xe4\x0f\xc0\xbd\x91o\xfbe\xf4\xad;\xd7t\xd8x\x82j\x98^\xdeG2v\xb9\xb1\t\xe0-\x05\xf9\xe9\x91\xe3\x97\xc7\x1f\x94\x87;t+Y\xd0\x19Z#=\xb1\xbe\x0e\xae_\xa1Yk&#Īg\f\u0085\xbc\xaam\x9e\x04\xd4]\xa8\xaf\xe5p0\x9f\xb0\xf2X\x02\xc4\a\xba\"T\xc9R\xe4.\xf6P\a\xa5ެ\xa1\xe3Z\x8a\x94)\xfb路4Uմ\xc54\x01&ȋ\xf1\x8b\xaf>7\xc1\x8f+Y\x13\xfc\x89\x85\x9f\x1b|\xeb\x83b!\xb4l\uf2497\xde\xc5ZwXO*;\xe9b@\b\xe4A1\xe3\xa9\xf9\x81i '\xb1^\xf30\xa4jֲ\x0e\xfc{\xd8\xe9\xfbj\xa1\xe3\x1eVU\xd8\x1d\xf1b\u007f\b\x01\xd0\x1a\x15\xbe\x8d\xfbnٿ3ʹ\x97\xbe\x11\xb0\xb6\xf7\xf4+4+\xb0\xc4\xe7HŮ\xe1X\xfbV\xcdR\xe89+\x9eJ\x8e\xa1\x98\xb2-\xa7\x01\xfbU\xf3^\a\xde\xd1ߕ8#\xd7\xd2\xd8\xff\xb9|d\xfa\x89\v9v/_K\xd0\xd7\xd2\xe0ӽ\x91㦶7j\xdc\xe3H\xd2\xc2\xf1H\xbc\xa4\x84ߨ\x96y\xf5\xf4\xfd\xf7\n\xc5L\x93+a\x19\x95\xc7AuYQ{\xf0\xcd;\x86\xc8\xd5vk\xa2\xee\xdb-\xf8\x0e\xad\xf6\x1bM\xcc5?\xb5\x1b\xe5\xadi\xb8)8\x8f\xb6\xfb\v&h\x17\x9cf\x90\xfb>\x13v㍢\x06flw\xfb\x81\x05\xa8\x19&\x1ad\xf3]\xab\xda#t\xb8\xa7\xe2}\b\x15y;\xab\x19Uh\u007f\x0e\x15\xda\xcb\x10\x14\x9f[\xb0\x11:\x89Q~\xf3$G{\x12c\x9b\xb2\xc8}\xda\vsZX\xca\xff\x1f˞\x91\x88\xfe\x97\x14\x94)=&\x17\xfe\x86ʖ\xef6\xdf\xf0\xbaN\x13\xb8\x85\xcb4\xb1\xbb\xb0\xa4\x1c\\\xa1b*\b\xec,\xbf\"\xa7\x1b\xd2\xf2\x8c<̥F\xc9P\a\x91\x8e\xeeaut\xd6:![ ڇ\xaf\xc4\xd1Y\x15/k\x1d\xcaJNa\b\xe3\b\xffv4\xde\x10\xb0[`?!vwRɎ?VZ\xf7\x1b\x97ڴ\xb9\xf3\xfb\xd2\xc7N\xdaب\xc0\xd8\xfcf\x8b8\x9a\xcaqˬ\xe8\xfa$U30]&\x88ט1\x95aL.\xc4j\x03.^\x8c\xebT\xb9\xbd\x11W\xd1Y\xd1j_\x84--1C\xa2\x01\xca'.\xe9nC\xd8>\xb8\xb9k;6\x05\x05\xa8Zµ\xcc\xe1F\xaa\xae\xfc\x8ev\xbcf\xfd\xf9\x0e\x8b\xb6\x81\x14\xc9s̳\xc7G;拺\xb1\u05cb\x0fi|\xfa\xef\u07fc\u007fj=\xef\xaa\aw/\x84bo\r\xb7_\x1d\xeb\xb0ﻻ6\x82\x16z.\r9\t\x97\xda3.\xcb\xdc\xdf\xecW\x1d\xf1\x9e\x1e\xab\xd4\xd9\x1c\xf2\x92Cw\xd3\xc1\x8d2\x95\xe1Ѡ\xfb\x95\x82\xfd\xb3l\xb7\xe8\r\x1e*\xfft\xd7A\xa8qR\x99\xd6\r\x8f\xaaeG\u007f\xc1\xfd\f_\xf2V\xa4\x87\xbc%\x15\xbe\tҝ\x05\xa9\r\xdeS\x12\xa6Qt-\x98\x9d\x99o\xcf\xe1\x1f\xef\xbcf\x17ְ\xed8t\xb0\x8fn\xe1:\xf2_݈\x88o9V.\x97\xbe\r\xa3\x8b\xe6n]\xce}F\vS\xaa\xd0\xfe\xbaT\xd8\x0f\xacnaB\x03\xe6<\x8aZ`\xb7\x1b\x06\xde/Ȥ\xb8c\vІ.\x8a'(\xe4\xd5\xe6\x1bv\x03\xa4\xcauU\xe9\xa4\xe9\"\xa8\x9bnuYŴn\xf5\x96\x8f\x1b\xb0\x1d\x18\xd4\xc9,h\xc8\t,A\x10\u007f\xc9\a#\xef\xce\x01\xd1\x01\xf4\x0e\x8d\x13\xb5\xc4X@\x80\x83\xf9\xbeS\xa9\bvի\xa6\xbeI\x11\xe1\xeaxN\r\x8c:o\x12\xeeu\x12;\xa5\x8e\xeb\x91\xfb\x04\x82/]#]\x94@\x19\xe6\x89\xd9\xed\xe5ܽ\x1dn\x1e\xf8\xab~\x0f\xa0\x80\xcc@X\x14wr\x1c\xafʺVO\x16\xb1\xfe\x04W\x0e\x9c;\xd7\x1d\xab\xa4<\xb4\xf0\xc5\n8A\xaalu\x99\xe1#\x9d\xb7\xacv]\xa0\xf77>\xde\x01\xd5]yK-D|\xdd|\xd6\xdb*\x0e\a\xb8\xf4\x8c\xba>y\xaec)S\xd0I\xfa~J\x12\xbf\x1cq\xc6\t)\xe6T?\xc5.o\xec3UK\xaeơ\xac8\xe5\xbb-s\x02Q.6\x81\x8f\xc85\xb4\xf0[\xce\xf1\xa1ƥ\xb9 v\xfdR\xf4\x81+\xcdZCȅu\xe0d\x81 \xea\x01\xe1YX\xe6a\xab\r\xb8L\xdayL\x88H\x8f[\xcf·a\xb5g(\x15\x0ekv\xc6dy\xa0\xfc=\x9a\xef\x1eq\x9c\x98\xffy\xf7֫h\x92a!\xaeꖺD\xf5\xee\xd3\xedß\xefz\xd50Ѓz\x96 -\bx\xe0\xf5\x03\xa6^\xe9\xe02\xe1\xc0 I\r\x95\xa3\x16\xa5\xc1U@&mH\x02h\x03%\x1a\xa9S\x99\x04D\xb9\xb3\xcdt\x95\xa7\xb0A\x02w\xddt(\x8d.\xd18\x19V\xa8/\x1d\x8bԩ\x1dp\xfc\x86&\xe5[y-BˊS\xaf;Lk\x1c\xbcnK\xdb\xf2\xcf\x00\xf7\b\x035\x12\n\xf4\xe6gL\xdc\x1a\xee\xd0\x10\x99\xc0u\xa2\xd5\x0e\r!\x90\xe8G%\xff\xd3ж\xa4\xb1\x8e\x15\xc9am6\xda\xc2\xeb\\\x89\x1cv\"\xaf\xf0\x02\x84J\xa1\x10{0H\xa3@\xa5:\xf4\xb8\x89]\xc3ߵA\x90j\xab\xaf s\xae\xb4W\x97\x97\x8f\xd2\x05K\x9c袨\x94t\xfbK6\xaarS9m\xece\x8a;\xcc/\xad|\\\t\x93d\xd2a\xe2*\x83\x97\xa2\x94+f]\xb15^\x17\xe9\x1f\x82D\xed\x9b\x1e\xaf\ak\xc5\x17\xb6\x97G$@\x86\xd3+\x8c\xef\xeag\xd1\x02MU\x84\xce盻\xfb\xae2I;D\x9fq\xefhX+\x02\x02L\xaa-֫qkt\xc14Q\xa5\xa5\x96\xca\xf1\x1fI.Q\r\xe1\xb7զ\x90\x8e\xe4\xfe\xef\n\xad#Y\xadᚷ'\xd2ê\xa4Փ\xae\xe1V\xc1\xb5(0\xbf\x16\x16\xbf\xb9\x00\bi\xbb\"`\xe3D\xd0\xddY\x87\x8d=j\x9d\x1f\xc2.8!\xaf\xb0\xc6\xefJLzK\x86\xfaɭLxa\xb0\xe5kL\xc0\xc0\xfa\xf92\xbej\xa16=\xd4|X\u007f\xd4\xda\xc4\xee\t\a4\xa161\xeb\x83_&\xd0䟰(i\xb9ΰx_7#\x16\t\xa3\xb4\xf1v\xc2f\x19̛\xae\xad\x1a\x1c\x18\x15\x1e.C\xc2k'\xd3\xdaj\x1c\xa0y\x1cQ\xcf\xd8VT\xb9{ \x97\x01\xed\xbd\xfe\x8c\xd6\xc9d\xac\xe5`\x12\xefG;\x06y\xa3%\x84]\x86\x86\x16'\xff\xc0\xf6n\x94.\U0001ac58\xb2\xc9\x13O\xb4en<\x02d;\xf3\x1cJ\x9d\xc2Ώ\x04\x9b}`\xfaP6\xad|6Z\xe7(\xc6P\xc3/I^\xa5\x986\x1e\xd5(.\x83\xd9\xde\x1ctb\xdfSHEZF\x9e\x1e\xb1\xaa\x9a_'\xe6\xc9\xfb\x950\bd(\xa4\xf24Az\xb7d3\xa1pT\xa4\xc3b\x82ϣ\x1a\xe9\v\xf9\xb8b\x93\xe3\x158S\x8d\xe9z\xa0!\x8c\x11\xfb#\x98\x05\xff|\tdM\x9fڜ\xe72a\x0f\xb41ڌ\x1aC31\xbf\xffC\xc02\xad\x9fb@\xfa\x1b\xb5k7'H\xf8\x18\x04\x1b\xcc\xc4Njc\x87\x1e\x0e~\xc1\xa4r8\xb5\x8e\x84\x83Tn\xb7h\x88\x16;ԍ\xff}\f\xac\xe3&\x82\x8a9.\xf8\x83y\xb5B'\xe11\x1aSSaSt{^\x80\xdc6\x02K/`+s\x87\xecK\xcd1\xdaqtf%\xf7\x92\x00\xc5\xee\xbdT\n\xe1\x92\xec\xa69\xd2F\xf4\x18`5$\xe0\xfd\xf2p\x86a\x19D\x90\x84Ʃ\xe0(\x884X\xf8\xe8\xca=\xaf\x8f\xb6\x86=\xc0w\x1f\xdfc:\a\x19\xc4k\xea\xc1\xa4\xde\r<\x9d.\v<\xc1(\x92\x9dI\xb1\x9b֜\xf1|\f\xed\x02\x04<\xe1\xde{V\xa3\x87˱B\xa2\x15\rI\x83\x1c\xd0c3\xf2\x84{&UG\xe8\xa2\xe8-Q\x15_\x9ep\x1f\xdbt\x00*\xf1W\xc7(<\xbaT\xc1\xb3\x88YJmi@\xad\xd7\x0e8\x1d7YXf\x94B\t\x88\x9f8\xedF`\xbd\xb0\xf4\x13\xee\xdfX/>Z5\x99,\x17 @\x06\x1b,\xf2\n\v\xf1\xd8\a\x91˴\x19\x8c\xd7\xc9\x02\x8a\xb7\xea\x02>jG\xff\xdc|\x91\x96XT)\xbc\xd7h?j\xc75\xdf\x14b?\x89\x13\x01\xf6\x9dyY*\xbf-\x10.\x8b\xc6oy\xe0-\x94T\xb4\x11\x9b\xb4p\xab\xe8|\xe6\xf1Y\"\xa6\f\x03s\x9e\xad\xa2\xb2\x1c\xd1UZ\xadx\x9b\x0e\xa3- \xda\xe5\xab\x16\x956=I],\xa48\xcab\xcd\xde=\xedV\xfe\x97\x83X\xf8\xb1b\xb0\xccE\x82)\xa4\x15\xc7\xdb9\xf0.\x1c>\xca\x04\n4\x8f\b%\xed\x1b\xf1J\xb5\xc0\x92\xfbr\x82\x16ƻ\x16\xa1\xd4\xdbB\x1a\xc7؊V}d\xcb \xe6\xa8\xe6\x13Q\xf6\xe3\xcd\xe3f\xc9\xdb;\xfbCQ\xe8wo\x8f\x97\xed,\v\xe5u\xe8\x83x&\xbd\xfbQ\b\x0e\xf6\xfeB\xdb+\xab\xf7\xafq\xbb\xa1\x90Ʈ\xe1\x1dߝ\xe7\xd8\xed\x1f\xa2\x84\x9d\xa1\xa2H\x12'\xd2\x02\xe9\xc9N\xe4\xe4>\x90\xf1V\x80\xb9w&\xf4\xf6\xc0\x83\x8a31ϙ\xb6~\xcf\xdfJ\xcc\xf9v\xeb\xfc\t\xf7\xe7\x17\a\xd6\xeb\xfcV\x9d\xc7\xd1$\x9b\u007f`\xb4\x1a\xafE\xab|\x0f\xe7\xfc\xdb9;fK\x96\xc8\t\xce\xdb\x02\xad\x8en\xca\xd7\xcfK\x8e\x02\x9c\xe1 \xdb\xe3usIK.\xfc\xdc,\xa2u\xba\xd4\xd6-b듶\xce\a\x00{\xee\xf6H\x840\xe6\xf4WG\rAl\x1d\x1a\xb0N\x9bp!Jfw\x10 '\xc9\xdbyٓ\xa8\x9bh\xa4'L\x87\xcc\xf3\xd6Bx\x9b~\xeeoJ\xe9\xff\xf34\x13v\x96\x98vit\x82\xd6ΫR\xe4\xce1\x13\xb0m\x82\xb5\xc2\x1f\u07b6Q\xa69&\x94\x1c\xca2W\x9c\xa0=\xe1`s\xf3\xa5\x13w&3D\u007fǨ\xf2)<\x02\xe7T\x15\x85\x18^\xceG\xb3{\xed{\x87\x05X\x13\xf3\a&\xf3X\xb1QY\xe67\xd7*\xf9[s<\n\xa9ny x\xfb͜\x15\b\xa6\x1cO=\xca\\\x87\xfe\xad@\x9a\x8a\xd8\xf3+\x84\xabf\xcdw5\x06{\x92=\xbcɈ\x97\x14\x903\xad\xb4\xeb\x06k\xea\x91\xdeX\xd8Jc]\xcb\xf0\x02\xaa\xd2\xf2u\xf2\xb7=c\xaa\x1bcN>b\xfe\xe4{w\u008a\x99~\xae\x13#\x96\x1c\xac\x03\xf8\x99\xd8!\xc8-H\a\xa8\x12])\x0ex\x91\xb9\xa0a\x16P\xf4B\xf4\x9bI\xe4\x9e\xd9鬪\"\x1e\x90\x15k\xa7T\xb3ѱn\x97\x1f\x84\x8c\x8bN\xc1ibu\xb2@]\xcdn\xedm\xe9gv\xf8\u07bd\f\x98B|\x91EU\x80(H,K\u038d[\x9f?\x18\xd2e\xbc\xac\x9f\x85tu\x06\xa1\xbfX]fM\x13]\x949:\x84\rn\xb5a{`e\x8a\x8d\xfbP\xcb\u007f4\xdfd\xaa\b\xd8\n\x99Wf\x81\x8d^,\x99\xa5\xe7\xb6\xda<\xbd\xfca,\x9e\x91\x15\x83\x19\x19t_\xe04\xcf\xef\x1f\xa5Y\xe62\u007f2\xf8\xf2\xaeii$i\xa9\x9e\xf3Ngi\xb2\xf7\xda\xf7Nk\xe5\x15j?\xe5\x9e\xceReN^\xddӦ\xbc\xba\xa7\xaf\xee\xe9\xab{:(\xaf\xee\xe9\xab{\xfaꞎ\x97W\xf7\xb4S^\xdd\xd3\xe8\xfd#\x86\xc3\x15t><;\x99\xab\xc8\x14\x8c9\xb6gƪ3\x8d\xae\xf3\xca:4K2\xa4o\xc7{\x8e\xe4\xd0'\xbeɊ?\x06\x9cҚ6u\xa5\xdd\xf4\x9a\x94iZ\x92a1\xf9o1\"\xbc\xf0\xe84\xe8\xe9l\xfb\xd8\x04\xba\xb9\xb4\xb9~\xeex\x93\xae\xe6\xff7\x01\x88\xd3a\xf8Zz\xfe\x1b\x9fn\xceU?\xf7\x8d\xcf\x01\x81\xe3\xdfd^ydZ\xdbL2\xdb\xf1D\xfc\xa9\x1d>`9\xb8\\\xe8\x83iz\x89߿i,#\xb2ͦs\xcc\xea[Ktb\xf7v\xdd\xff\xc5\xe9:\xe3lbf\xcf\xd2e\xfe\xfb#:\xba\xaa\xc7nZ{\xd0\xd3\xfaۿ!\xc6\x13\x14\xb5\x01%s/\x80@\xa1\a?\xfcT\xfa#\xf2\xc9\xeb|\xfe\xa0\x16\x9f\x97\xb64\x1b\xad\xc9\x1f\x9a\xdfU\xbe\"\am\xd9\a\x02\xb3\xf9f1LCL\x96\xd9x\xfe\xd8\f\xd5%\xb9e\xb1g\xf0\x88<\xb2\xf8\xec\xb18x\x80\xbf؍\xcd\x19\x8b\xf6\xdab\xf3þMVXd.X'\xc3k\x96\xe4\x89\x19`р\xc5e{E\xe7xu2\xb7\xe6\xd1:\x92\xd95\x9e\xaf5Kr,\x9f+&K+\x8a\xd7\xe8ܬ&\xe3j>\x92\xf8U\x19Y/\x9f\xfb\xfd\x92~\xfe\xf1\xfc\xaa\xa8\xac\xaa\xa8\xb3\xc0<\xcfQySK\xb3\xa5\xa2P]\x9a\x19\xd5d=\x1d\x198*\x1f\xea0\xd7\xe9\xd8Tf\xb3\xa0\xa63\x9c\x8e\x91\x1d\xcb}\x8a\xc8k:B\xb2\x9b\xf1\xb4\xd8\r\x98զ\x99\x06\xe3_Շ2\xbf\xd7\xe6\xff\v\r\xfc\xdaIk\x93\xa2\x99=\x95,a}\x96\xed~\xbcr0\xfe\xe0s\x9d\xf019\xb5\xea\x9ex\xa6\xbc(\xdd|>\x92\xc0\x8fR\xa5^\x93h\xb1t|\x1a~\xa1\x82\x13\xcc\x1a7k:\xe3\xb6\xf5h\a\xa7-\x8b\xa5 \xa3\x9e\xc2f\xef\xa3Bv\r7\"ɚ\x86\x13\x14y\xe4LX:\xd9\x17\xc2\xc1ys\x8c\xbd\f=\xa9\xe6|\r\xf0\x83n\"\b\x9d\xcfC'\xe8ZY\x94\xf9\x1e*\x8bp\xde'\xf4u\xa7\xb0IݱJ\x946\xd3\xe1%\x81\x88\x83\xd8]\xbf\xc7H\xbc$\xbc#\x90\xe4\xbaJ\x9b\x11\x8e\x88[\xa8=|z`O\x8e\xbf\x9eNگ\xcckO-\x9c\xab\x06\x1f\xa1O\x90\x9cz\xb6\xef\xa9\x1a 럖\xf3f\x9c\x81\v\xef\xd0\x1cB7\xb3\xfe\xa7\xd7\xfe\xb8G\xbd\x1a\u007f\xfaeռFs\x16\x81\xac\u007fo,\xe6\x81\x1f\xff\xa8[\"JW\x99z{M*\xc3\x0fN\x10\x11\xf4\xef1\x9c\xf6\xc4O\xfb\xdcٌ,\xdb\a\xd0\xda\b\xc3\xecsk#\xf2k\x1e\v\x9a|=\xc7\xef\xae\xfe9\xb4\x15\xd1?M\x9c\xa3\xeb\x80\x1f蘙\xe9'j\xd3\u070e\xd7@s\xc7\xf0\xb0\xc7\xdd\x14\xeb\xe3ם+\xf8\x88\xcf#\xb57\x8a&qx\x18\xf5w\x9a\x98r\x84b\xecy\xb3\xa3S\xdc5\xbd\xf8By\xc4Z\xf4\xcdܠ\xf9 R-\xf2\xbcC\xd1_\x1e\x8f\x89\xf5\x8fr\xeb\xc3F\t\xcd\xe9O\a-&\r\xd7Q\xa35e\xb0F\x97\xd4A\xa5E\xb3ô\xa3$\xf5\x1eޭ\xa96\a\xef\xac\xd4\v\x13~\xf9\xf5\xac]\xa3\"I\xb0t\xf5\xfdH\xf7\xfd\xc9\xf3s\xfe#\xa4\x05\xbc\xeb\v\xfa\xd0\xc2o9LJ\x1a\x97\xe6\x82\xd8\xf5K\xd1\a\xae4k\xf1,\x91*I\xad\xb3=\xdc\u007f/f(\xeak\xa5\x15\xb5q\xd0\xeb\xc1|I\xcc%\x87\xc3\xf9\xe6pij\xd5ju&J\xf9\x80\xc6J\xad\xae@\x94\x12\xbf8T\xf4\x97]?\xfdծ\xa5\xbeܽ={\x92*\xbd\x82\xeb\xca:]|F\xab+\x93\xe0{\xdcJ%\x9d\xd4\xea\xac@'R\xe1\xc4\xd5\x19\x80PJ;Aݖ\xfe\x04H\xb4rF\xe79\x9a\xd5#\xaa\xf5S\xb5\xc1M%\xf3\x14\r\x03\x0fK\xef\xbe[\xffe\xfd\xdd\x19@b\x90\xa7\xdf\xcb\x02\xad\x13Ey\x05\xaa\xca\xf33\x00%\n\xbc\x02\x9bd\x98V9\xda\xf5\x0es4z-\xf5\x99-1\xa1\xd5\x1e\x8d\xae\xca+h\u007f\xf0\x93jL\xfc.\xee\xea\xf9ܕK\xeb~\xecu\u007f\x90\xd6\xf1Oe^\x19\x91w\xd6\xe3^+\xd5c\x95\v\xd3\xf6\x9f\x01\xd8D\x97x\x05\x1fi\xa9R$\x98\x9e\x01\xd4\x1b\xe3\xa5W ҔI%\xf2OF*\x87\xe6Z\xe7U\x11H\xb4\x82\x14mbd\xe9\x98\x14wN\xb8ʂނ˰\xbb\x0e\xb5\x9f\xadV\x9f\x84ˮ`myܺ̄\r\xbfz\x12y\x00u\x97\xdb\x13n\xd6\x19\xa9\x1e\xc7V{\a\xd7F+\xc0/\xa5AK(CʜU\x8f\xf0\x9c\xa1\x02\xa7\xc1T\x8aQ\xf9^$OU9\x82H\x89\xc9z\x80g\x8dI\xbfs\x0e\x97\xfb\f!\x17ց\x93\x05\x82\xa8\x17\x84ga\x19\x87\xad6\xe02i\xe7iB@z\xd8zt>\f\xbb=B\xa9pX\xa3\xd3\x01\x15\xa4z} \x91=\x98\xef\x1eq\x1c\x98\xffy\xf7\xd6\xcbM\x92a!\xaeꑺD\xf5\xee\xd3\xedß\xefz\xdd0\x90\x83z\x97 -\bx`\xa1\x06S\xab\x1f\xb8L80H\\C\xe5hDip\x15(\x936 \x01\xb4\x81\x12\x8dԩL\x02Ey\xb2\xcdt\x95\xa7\xb0A\"\uee99P\x1a]\xa2q2\xa8\x8do\x1d3\xd1\xe9\x1d`\xfc\x866\xe5Gy)B˂S+\x03\xa65\x1d\xbclK\xdb\xe2\xcf\x04\xee\x01\x06\x1a$\x14\xe8\xcdϘ\xb85ܡ!0\x01\xebD\xab\x1d\x1a\xa2@\xa2\x1f\x95\xfcO\x03ے\xc4:\x16$\x87\xb5.\xb7\x8d\x95O\x89\x1cv\"\xaf\xf0\x02\x84J\xa1\x10{0H\xab@\xa5:\xf0x\x88]\xc3ߵA\x90j\xab\xaf s\xae\xb4W\x97\x97\x8f\xd2\x05\xf3\x98袨\x94t\xfbK\xb6trS9m\xece\x8a;\xcc/\xad|\\\t\x93d\xd2a\xe2*\x83\x97\xa2\x94+F]\xb1\x89\\\x17\xe9\x1f\x02G\xed\x9b\x1e\xae\a\xba\xe2\x1b\x1b\xb1#\x1c k\xe6\x05\xc6O\xf5\xbbh\tM]D\x9d\xcf7w\xf7]a\x92vH}\xa6{G\xc2Z\x16\x10\xc1\xa4\xdab\xad\x8d[\xa3\v\x86\x89*-\xb5T\x8e\xffHr\x89jH~[m\n\xe9\x88\xef\xff\xae\xd0:\xe2\xd5\x1a\xae\xd9g\x90\x1cV%iO\xba\x86[\x05ע\xc0\xfcZX\xfc\xe6\f J\xdb\x15\x116\x8e\x05]w7\x1c\xec\xa9\xd6\xf9!\xb8\xa6\t~\x05\x1d\xbf+1\xe9\xa9\f͓[\x99\xb0b\xb0\xe5kL\xc0\xc0\xfa\xf96\xae\xb5P\x9b\x1e\x1a>\xec?jmb}\xc2\x01L\xa8M\xcc\xfa\xe0\x97\tj\xf2OX\x94\xa4\xae3(\xde\xd7\xc3\bE\xa2Qڄ \xc1Y\x06\xf3\xa6k\xab\x06\aF\x85\x97ː赓im5\x0e\xa8y\x9c\xa2\x1e\xb1\xad\xa8r\xf7@~\x1c\xed\xbd\xfe\x8c\xd6\xc9dl\xe4`\x13\xefG'\x06~\xa3%\n\xbb\f\r)'\xff\xc0\xf6n\x14.\xb0\xceXL\xd9\xe4\x89'r\x99\x1bO\x01\xb2\x9dy\x0e\xa5Na\xe7W\x82\xcd> }ț\x96?\x1b\xads\x14cT\xc3/I^\xa5\x986a\xce(]\x06\xbb\xbd9\x98\xc4\x01\xa1\x90\x8a\xa4\x8c\xc2/BU5\xbfN\xec\x93\xfd\x950\bd(\xa4\xf20A\xfa\xb0d3!pԤ\xc3b\x02ϣ\x12\xe9\x1b\x05\x9eb\x93\xe3\x158S\x8d\xc9z\x80!\x8c\x11\xfb#4\vA\xf3\x12\x925sjs\x9e\xcb\x04\x89X\x8d\xd1f\xaa1i&\xf6\xf7\u007fH\xb0L\xeb\xa7\x18\"\xfd\x8dƵ\xce\t\x12>\x9b\xc0\x063\xb1\x93\xda\xd8a\x84\x83_0\xa9\x1cN\xe9\x91p\x90\xca\xed\x16\r\xc1›\x89\xbf\x8f\x11븉\xa0f\x8e3\xfe`_-ӉyL\x8d\xa9\xad\xb0)\x9e\x84\n\x8c8Y\xec\xaa\x04\xa9R\xb9\x93i%r\x90\xca:\xa1\x12\xbf?\xd1\xe07\xbe?\x98\x13\x88\x03\xfc\xbd\x01\x0e\xbb .\xf5<\x9bVH\xe1h\xa1\u0378p\x84v\bf\x9a\f\x1bA\x16PO\xb9\xa3\xb6\x19:\xc5ը\xa4\xecR[\xbbs\xd1r\xca\a\x85\xb9\xd8`\x0e\x16sL\x9c6\xd3\xe4\x89\x11\x02\xdfb\xed\xe7\x04eG,i\xeb3HPg\x8dhۜ\x86\xe7L&\x99\x8f\xdfH\xca\x18\x16\xa4\x1a-[\fQ\x96\xf9\xfeئ!F2\xea\xc5\xe6\x8cF\xdb\"\xcc\xc7\x10\xee\x94!i[\xa4\rnی5\xeeS\xbd\x11\x9bW\xa2\xf7\xd0T_%\xec\xb7\a\xd3_^؉ܒ\xcew\xb7[\xc0\xa2t\xfb\v\x90.\xf4\xc6@\xa5\x00\xab\xc5\xe3wƸӴ\xe5v8\xfbŵ\xe5E\xb8֠\xf1;a\x1a;\xab\xbb\xdaW-b؇\xee\xcc\v\x90ۆa\xe9\x05le\xee\x90c\xa99D;\x81\xce,\xe7^\x92@\xb1\xbe\x97Z!\\\x92\xdd4Gڈ\x19\x03Z\r\x01\xf8\xb8<\x9ca\x98\a\x11 \xa1\t*8\v\"\r\x16>\xbbr\xcf\xfa\xd1\xf6p\x04\xf8\xee\xe3{L\xe7H\x06\xf1\x92z\xb0\xa9w\x83H\xa7\x8b\x02o0\ndgS\x1c\xa65g<\x9fC\xbb\x00\x01O\xb8\xf7\x91\xd5\xe8\xe1r\xac\x11kE\x03\xd2 '\xf4،<\xe1\x9eA\xd5\x19\xba(xKDŷ'\xdc\xc7\x0e\x1d\x10\x95\xf0\xabs\x14\x9e\xba\xd4\xc1\xbb\x88Q\xa5\xb65D\xadu\a\x9c\x8e\xdb,,3J\xa1\x05\x8a\x9f\xb8\xed\x86a\xbd\xb4\xf4\x13\xee\xdfX\xcf>ҚL\x96\v(@\x06\x1b,\xb2\x86\x85|\xec\x83\xc8e\xda,\xc6z\xb2\x00⭺\x80\x8f\xda\xd1?7_\xa4%\x14U\n\xef5ڏ\xdaq\xcf7%\xb1\xdfĉ\x04\xf6\x93Y-\x95w\vD\x97E\xeb\xb78\xb0\v%\x11m\xd8&-\xdc*:\x9fy\xfa,aS\x86\x019\x8fVQY\xce\xe8*\xadV\xec\xa6\xc3j\v\x80v\xf1\xaaY\xa5M\x8fS\x17\v!\x8e\xa2X\xa3wO\xde\xca\xffr\x90\v?\xd6\f\x96\xb9H0\x85\xb4\xe2|;'ޅ\xc3G\x99@\x81\xe6\x11\xa1$\xbf\x11/T\v,\xb9o'Ha|h\x11Z\xed\x16\xd28\xc4V\xa4\xf5\x91#\x03\x9b\xa3\x86Odُ\x0f\x8f\xdb%\xbbw\x8e\x87\xa2\xa8߽\xd2]\xe6Y\x16\xf2\xeb0\x06\xf1H\xfa\xf0\xa3\x10\x9c\xec\xfd\x85\xdc+\x8b\xf7\xafq\xdePHc\xd7\xf0\x8e/\xb4s\xec\xce\x0fY\xc2\xceRQ \t\x13i\x81\xe4d'r\n\x1f\xc8x+\xc0\xdc\a\x13z{\x10Ař\x98\xe7L[\xef\xf3\xb7\x12s\xbe\xdd:\u007f\xc2\xfd\xf9Ł\xf5:\xbfU\xe7q0\xc9\xe6\x1f\x18\xad&j\xd1*\xdf\xc39\xffv\u0381\xd9\x12\x159!x[ \xd5\xd1C\xf9\xfay\xc9Q\x80\xce\xda!j\xa1\xc9\xcd%-\x85\xf0s\xbb\x88\x96\xe9R[\xb7\b\xadO\xda:\x9f\x00\xec\x85\xdb#\x19\u0098\xd3_\x9d5\x04\xb1uh\xc0:m\u0085(\x99\xddA\x82\x9c8o\xe7yO\xacn\xb2\x91\x1e0\x1d2\xcf[\v\xe1m\xfa\xb9\xbf)\xa5\xff\xcf\xc3L8Xbإ\xd1\tZ;/J\x91\x9ec&a\xdb$k\x85?\xbcm\xa3LsL*9\xb4e\xa18\x91\xf6\x84\x83\xcd͗Nޙ\xcc\x10\xfd\x1d#ʧ\xe0\b\\\xe8T\x14bx9\x1f\x8d\ued5f\x1d\x14\xb0\x06\xe6\x0fL\xe6\xb1b\xa3\xb2,n\xaeE\xf2\xb7\x16x\x14R\xdd\xf2B\xf0\xf6\x9b\x05+\x10L9\x9ez\x94\xb9\x0e\xf3[\x864\x1d\xb1\xe7W\bW͚\xefj\f\xf68{x\x93\x11\xcf)\xa0`Zi\xd7M\xd6\xd4+\xbd\xb1\xb0\x95ƺ\x16\xe1\x05P\xa5\xe5\xeb\xe4o{\xc6T7Ɯ|\xc4\xfc\xc9\xcf\xee\xa4\x153\xfd\\\x17F,9X\a\xe2gb\x87 \xb7 \x1d\xa0Jt\xa58\xe1E悖Y\x00\xd13\xd1;\x93H\x9fٙ\xac\xaa\"\x9e +\x96N\xa9f\xb3c\xdd)?\b\x19\x97\x9d\x82\xd3\xd8\xead\x81\xba\x9au\xedm\xebWv\xf8ٽ\n\x98B|\x91EU\x80(\x88-K\u038d[_?\x18\xcae<\xaf\x9f\x85tu\x05\xa1\xbfX]fM\x13]\x949:\x84\rn\xb5a{`e\x8aM\xf8P\xf3\u007f\xb4\xded\xaa\t\xd8\n\x99Wf\x81\x8d^̙\xa5\xe7\xb6\xda<\xbd\xfca,\x1e\x91\x15\x1332\xe9\xbe h\x9e\xf7\x1f\xa5Y\x162\u007f2\xf8\xf2\xa1ii$I\xa9\x9e\x8bNgar\xf4ڏNk\xe1\x15j?\x15\x9e\xceBeL^\xc3Ӧ\xbd\x86\xa7\xaf\xe1\xe9kx:h\xaf\xe1\xe9kx\xfa\x1a\x9e\x8e\xb7\xd7\xf0\xb4\xd3^\xc3\xd3h\xff\x11\x83\xe1\x8a3\xb7G\x06Da\x15Y\x821\x87\xf6\xccZu\xa5\xd1u^Y\x87fI\x85\xf4\xed\xf8̑\x1a\xfa\xc4\x0fY\xf1\x17zSRӖ\xae\xb4N\xaf)\x99&\x95\f\xca\xe4\xbfň\x88£ˠ\xa7\xab\xedc\v\xe8\xe6\xca\xe6\xfa\xb5\xe3M\xb9\x9a\xff\xdf\x04A\x9c\x0e\xcb\xd7\xdc\xf3\xdf\xf8tk\xae\xfa\xb5o|\x0e\b\x18\xff&\xeb\xca#\xcb\xdaf\x8aَ\x17\xe2Oy\xf8@\xcb\xc1\xe5B\x9f\x98\xa6W\xf8\xfd\x9b\xa6eD\xb5\xd9t\x8dY}k\x89N\xecޮ\xfb\xbf8]W\x9cM\xec\xecY\xba\xcc\u007f\u007fDGW\xf5\xd8-k\x0frZ\u007f\xfb7\xa4\xf1\x04Dm@\xc9\xdc3 @\xe8\x91\x1f~*\xfd\x11\xf9d=\x9f?\xa8\xc5ץ-\xadFk\xea\x87\xe6\xbd\xcaWԠ-\xfb@`\xb6\xde,\x06i\x88\xa92\x1b\xaf\x1f\x9b\x81\xba\xa4\xb6,\xf6\f\x1eQG\x16_=\x16G\x1e\xe0/vckƢ\xa3\xb6\xd8\xfa\xb0oS\x15\x16Y\v֩\xf0\x9a\x05yb\x05X4\xc1⪽\xa2k\xbc:\x95[\xf3\xd4:R\xd95^\xaf5\vr\xac\x9e+\xa6J+\n\xd7\xe8ڬ\xa6\xe2j>\x93\xf8U\x15Y/_\xfb\xfd\x92q\xfe\xf1\xfa\xaa\xa8\xaa\xaa\xa8\xb3\xc0<\xceQuSK\xab\xa5\xa2\xa8\xba\xb42\xaa\xa9z:\xb2pT=\xd4a\xadӱ\xad\xccVAMW8\x1d\x03;V\xfb\x14Q\xd7t\x04d\xb7\xe2iq\x180+M3\x03ƿ\xaa\x0fm\xde\xd7\xe6\xff\v\t\xfc\xdaMk\x93\xa2\x99=\x95,A}\x16\xed~\xber\xb0\xfe\xe0s\x9d\xf019\x8d\xea\x9ex\xa6\xa2(\xdd|>\x92\xc0\x8fR\xa5^\x92HY:1\r\xbfP\xc1\x05fM\x985]q\xdbF\xb4\x83Ӗ\xc5R\x90QOa\xb3\xf7Y!\xbb\x86\x1b\x91d\xcd\xc0\t\x88\xbcr&,\x9d\xec\v\xe1\xe0\xbc9\xc6^\x86\x99\xd4s\xbe\x06\xf8A7\x19\x84\xce\xe7\xa1\x13p\xad,\xca|\x0f\x95E8\xef\x03\xfa\xbaSؤ\xecX%J\x9b\xe9\xf0\x92@\xc4A\xec\xae?c$_\x12\xde\x11Hr]\xa5\xcd\nG\xd8-\xd4\x1e>=p$\xc7_O'\xedW\xe6u\xa4\x16\xceU\x83\x8f\xd0'@N=\x1e\xb1\x88d\xd3Y\x15\xeb\xb4\x11\x8f\xf8A\xfbw5bh֟\xd1{Z\xa5\xb6\xab!\xc7Z\x17MNJ\xb2\xdf\xdb\x10`{\xf5Rk[\x9b\x84\"l\xa7L\ue31e;\x97Gl\xee\xfe\xfe\x83ߐ\x93\x05\xae\xdfW>õ*\x85\xb1H\x94\x0e\x1b\xf5\x936Ӗ0\xd3ϐ\xeb\x9a\x0e\xdf\x0f\xf7a\x90\xafz8\x99v\xd2n\xfc\x13\x16A|\x03\xe9bD\xfea|f\xe7\xb0\xdcaⱜ\x98\xdeN\xc2\x12\xd6\xeaD\xb2-\xe2\x14\x05߰|\xbb7\x16\x8eEdGLFe\xf1\xa7g\x85\xe6sPT{\xab<\xa7f^]\xf9\xc7\xc1\xc4\xc0\xe01\xf3A\xf6o0|\xcc署@ֿ\xf7\xe6\xcd8\x13.\xbcCsH\xba\x19\xfd\x9f\xd6\xfd\xf1\x88z5\xfe\xf4˪y\x8d\xe6,\x82\xb2\xfe\xbd\xb1\x98\a~\xfc\xa3n\x89(]ej\xf7\x9aT\x86\x1f\x9c \xe8\xdfc8퉟\xf6\xb9\xb3\x19^\xb6\x0f\xa0\xb5\x19\x86\xd9\xe7\xd6F\xf8\xd7<\x164\xf9z\x8e\xf7\xae\xfe9\xb4\x15\xc1?\x8d\x9d\xa3z\xc0\x0ft\xcc\xec\xf4\x13\x8din\xc7kB\xf3\xc4\xf0\xb0\xc7\xdd\x14\xea\xe3ם+\xf8\x88\xcf#\xbd7\x8a6qx\x18\xf5w\x9a\x98r\x86b\xecy\xb3\xa3[\xdc5\xb3\xf8By\xc4Z\xf4\xcd\xdc`\xf8 S-\xf2\xbc\x03\xd1_\x1e\x8f\xb1\xf5\x8fr\xeb\xd3F\t\xed\xe9O\a#&\r\xd7Q\xa35e\xb0FU\xea\xa0Ӣ\xd9a\xda\x11\x92ڇw{\xaa\xcd\xc1;+\xb5b\xc2/\xbf\x9e\xb5:*\x92\x04KWߏt\x1f\x859\xb8S\x1d\xda;\xc5\xf8\xbf' 2\xcde$\xf6m)\x98Nѹpfm\xf20\x8e\xb9\x1b\xf9Z\xe9\xeem\x8f:f0\x92\x18\xb5Mktj\x0fh=\x81ZS\xa9ބ$i\xfcK,\xc3$\xc9hf\xf3%\xf6\xe7\xebh\xd6\xc7Iz9(\xc6\xf9\xe5\f\xd3C\x94\x99\xfb\xb7\xa6E}\xd2\x16\xb3\x89N\xd64ׯύڀ\xfc\xbf\xd9\x1b\xb7\bw\x1eY\x96J\xff\xb0騞\f\xe8\xc1\x10Pp.\xf6\xedbB& \xf3I\xbe\x901\x82\xdd\n\x9aU<\x9f\\\xeb\xd3&\xa0\xa2c%\xb9\x9fpH\xf6\xe0'\xe3Z1x;\xd7\xf9,\x87כ\b\xcd'\xfdI\xff\x9br\x1c7\x86p\xd5w\x99P\xad>D\x8fk\x8c\xaf\xf7׀2X\xabv\x16k\x10\nK\xed\xac\xab\x88\xd4i^5c\xa9]\xf6\xa9W\nh\xa1\x10\xfb\xe4\xe5\x80\xeeV7\xc0\x8b\x9aO\xf9+ϰ;\xddR\xbd;/\x87˖ʥ[C\x9cݥ\x98\x15\xce\xdeD\xcaj\xf6rI\xafn\x1e\vB\xb6S\xd9qf\\\xb5Ƹ\x88,c\xb8\ta5ً\xcbd\xbe\x99\x84\xc7\xe2I\xed\xa7\x01s\u061d\xff\xf4c \xc3H\x86?\xff*.\xd39.s\xbd`s?߂߽\xbbZgӧ\xf6\xae1y\x89\x87\x9f\u007f)\xb2cl\x9e\xc6\x1d4^\xfe\x1d\x00\x00\xff\xff;,8\xce>\f\x00\x00"), []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xb4VM\x8f\xdb6\x10\xbd\xebW\f\xd2C.\x95\x9c\xa0\x87\x16\xba\x05n\x0fA\xd3`\x11\xa7\xbe\x14=\xd0\xe4Ȟ.E\xb2\x9c\xa1\xdb\xed\xaf/HQ돕\xb7Y\xa0э\xc3\xe1\x9b7o>\xec\xa6m\xdbF\x05\xdabd\xf2\xae\a\x15\b\xff\x16t\xf9\xc4\xdd\xfd\x0fܑ_\x1d\xdf6\xf7\xe4L\x0f\xeb\xc4\xe2\xc7O\xc8>E\x8d?\xe2@\x8e\x84\xbckF\x14e\x94\xa8\xbe\x01P\xceyQ\xd9\xcc\xf9\b\xa0\xbd\x93\xe8\xad\xc5\xd8\xee\xd1u\xf7i\x87\xbbD\xd6`,\xe0s\xe8\xe3\x9b\xee\xfb\xeeM\x03\xa0#\x96\xe7\x9fiD\x165\x86\x1e\\\xb2\xb6\x01pj\xc4\x1e\x8eަ\x11٩\xc0\a/\xd6\xeb)XwD\x8b\xd1w\xe4\x1b\x0e\xa8s\xec}\xf4)\xf4p\xba\x98 *\xaf)\xa7mA\xdbT\xb4\x0f\x15\xad8Xb\xf9\xf9\x19\xa7\x0f\xc4R\x1c\x83MQٛ̊\x0f\x93\xdb'\xab\xe2-\xaf\x06\x80\xb5\x0f\xd8\xc3\xc7L1(\x8d\xa6\x01\xa8\xf2\x14\xca\xed,\xc0\xdb\tQ\x1fpTS.\x00>\xa0{w\xf7~\xfb\xdd\xe6\xc2\f`\x90u\xa4 E\xe4\xe5D\x80\x18\x14\xccL\xe0\xaf\x03F\x84mQ\rX|D\xae\xa4\x1fA\x01f\xfe\xdc=\x1aC\xf4\x01\xa3\xd0,\xf0\xf4\x9d\xb5י\xf5\x8a\xd7\xebL}\xf2\x02\x93\xfb\n\x19\xe4\x80s\xfahj\xb6\xe0\a\x90\x031D\f\x11\x19\x9d\x9c\xcau\xfa\xfc\x00ʁ\xdf\xfd\x81Z:\xd8`\xcc0\xc0\a\x9f\xac\xc9\xedx\xc4(\x10Q\xfb\xbd\xa3\u007f\x1e\xb1\x19ė\xa0V\t\xd6ʞ>r\x82\xd1)\vGe\x13~\v\xca\x19\x18\xd5\x03D\xccQ \xb93\xbc\xe2\xc2\x1d\xfc\xe2#\x02\xb9\xc1\xf7p\x10\tܯV{\x92y\xac\xb4\x1f\xc7\xe4H\x1eVeBh\x97\xc4G^\x19<\xa2]1\xed[\x15\xf5\x81\x04\xb5\xa4\x88+\x15\xa8-\xd4\xdd\xd4\xed\xa3\xf9&\xd6A\xe4\xd7\x17\\\xe5!w\x11K$\xb7?\xbb(\xed\xfeL\x05r\xa7O\x8d0=\x9d\xb28\t\x9dMY\x9dO?m>\xc3\x1c\xba\x14\xe3Z\xfd\xa2\xfb\xe9!\x9fJ\x90\x05#7`\x9c\x8a8D?\x16Lt&xrR\x0e\xda\x12\xbak\xf99\xedF\x92\\\xf7?\x13\xb2\xe4Zu\xb0.\xbb\x06v\b)\x18%h:x\xef`\xadF\xb4k\xc5\xf8\xd5\v\x90\x95\xe66\v\xfbe%8_\x93\xd7Γj\xe7\x03V\x97؍z-O\xf2&\xa0\xbe\x18\xa0\x8cB\x03\xd5\xc9\x1e|\xbc\xd2U\xcds\xbe\x8c\xd7]\xb8/\x0f8L;~\xa0\xfd\xb5\x15@\x19S~!\x94\xbd\xbb\xf9\xf6\x19\xc1\x16\xf2^\x97H\xb9Q\a\x1f3\xa3#\x19\x8c\xed\x9cge\x92bM\x98\xd0\x1a\xee\x9e@\xdeм&Y \x9fҼ\xe0qW\xdd2\x93,\xf4\xfcl\xdaPX\x17fY\x9fj\x8f\xb7\x18,d\x9c;\x9c\"^\xcdj\xfb\x18\xe0\x8bzG\x94$~y\xf7\x94g\xd5sW;H\xa7\x18\xd1I\xc5\\ش\xffO\a\x85\x83b\xfc\x0f͗#\xdc\xe5\x97s\x19,\r\xa8\x1f\xb4\xc5\t\x10\xfc\xb0\xd0m/\xa2\x9c?ti|ʭ\x85wGEV\xed,.\xdc\xfd\xea\xd4\xcdۛ\xc5_\xac\xe7\x13#\xe7ujz\x90\x98&\xec\xdae\xd5r\xaa\xbe\xd2\x1a\x83\xa0\xf9x\xfd\xaf\xe7ի\x8b?.娽\x9b\x86\x95{\xf8\xed\xf7fBE\xb3\x9d\xff\x81d\xe3\xbf\x01\x00\x00\xff\xff\xbf\xca\xff\xa71\n\x00\x00"), } diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 0e95ec2f6..0438c7538 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -72,6 +72,26 @@ rules: - get - patch - update +- apiGroups: + - velero.io + resources: + - resticrepositories + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - velero.io + resources: + - resticrepositories/status + verbs: + - get + - patch + - update - apiGroups: - velero.io resources: diff --git a/pkg/apis/velero/v1/restic_repository.go b/pkg/apis/velero/v1/restic_repository_types.go similarity index 78% rename from pkg/apis/velero/v1/restic_repository.go rename to pkg/apis/velero/v1/restic_repository_types.go index d78f8851b..6a44c2a31 100644 --- a/pkg/apis/velero/v1/restic_repository.go +++ b/pkg/apis/velero/v1/restic_repository_types.go @@ -64,9 +64,15 @@ type ResticRepositoryStatus struct { LastMaintenanceTime *metav1.Time `json:"lastMaintenanceTime,omitempty"` } +// TODO(2.0) After converting all resources to use the runtime-controller client, +// the genclient and k8s:deepcopy markers will no longer be needed and should be removed. // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - +// +kubebuilder:object:root=true +// +kubebuilder:object:generate=true +// +kubebuilder:storageversion +// +kubebuilder:subresource:status +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" type ResticRepository struct { metav1.TypeMeta `json:",inline"` @@ -80,7 +86,12 @@ type ResticRepository struct { Status ResticRepositoryStatus `json:"status,omitempty"` } +// TODO(2.0) After converting all resources to use the runtime-controller client, +// the k8s:deepcopy marker will no longer be needed and should be removed. // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:object:root=true +// +kubebuilder:rbac:groups=velero.io,resources=resticrepositories,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=velero.io,resources=resticrepositories/status,verbs=get;update;patch // ResticRepositoryList is a list of ResticRepositories. type ResticRepositoryList struct { diff --git a/pkg/apis/velero/v1/schedule_types.go b/pkg/apis/velero/v1/schedule_types.go index a3987180d..ab950eab7 100644 --- a/pkg/apis/velero/v1/schedule_types.go +++ b/pkg/apis/velero/v1/schedule_types.go @@ -84,7 +84,6 @@ type ScheduleStatus struct { // +kubebuilder:object:root=true // +kubebuilder:storageversion // +kubebuilder:subresource:status -// +kubebuilder:printcolumn:name="Name",type="string",JSONPath=".metadata.name",description="Name of the schedule" // +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.phase",description="Status of the schedule" // +kubebuilder:printcolumn:name="Schedule",type="string",JSONPath=".spec.schedule",description="A Cron expression defining when to run the Backup" // +kubebuilder:printcolumn:name="LastBackup",type="date",JSONPath=".status.lastBackup",description="The last time a Backup was run for this schedule" diff --git a/pkg/cmd/server/server.go b/pkg/cmd/server/server.go index 271051f67..e5f326724 100644 --- a/pkg/cmd/server/server.go +++ b/pkg/cmd/server/server.go @@ -739,29 +739,12 @@ func (s *server) runControllers(defaultVolumeSnapshotLocations map[string]string } } - resticRepoControllerRunInfo := func() controllerRunInfo { - resticRepoController := controller.NewResticRepositoryController( - s.logger, - s.sharedInformerFactory.Velero().V1().ResticRepositories(), - s.veleroClient.VeleroV1(), - s.mgr.GetClient(), - s.resticManager, - s.config.defaultResticMaintenanceFrequency, - ) - - return controllerRunInfo{ - controller: resticRepoController, - numWorkers: defaultControllerWorkers, - } - } - enabledControllers := map[string]func() controllerRunInfo{ controller.BackupSync: backupSyncControllerRunInfo, controller.Backup: backupControllerRunInfo, controller.GarbageCollection: gcControllerRunInfo, controller.BackupDeletion: deletionControllerRunInfo, controller.Restore: restoreControllerRunInfo, - controller.ResticRepo: resticRepoControllerRunInfo, } // Note: all runtime type controllers that can be disabled are grouped separately, below: enabledRuntimeControllers := make(map[string]struct{}) @@ -833,6 +816,10 @@ func (s *server) runControllers(defaultVolumeSnapshotLocations map[string]string s.logger.Fatal(err, "unable to create controller", "controller", controller.Schedule) } + if err := controller.NewResticRepoConciler(s.namespace, s.logger, s.mgr.GetClient(), s.config.defaultResticMaintenanceFrequency, s.resticManager).SetupWithManager(s.mgr); err != nil { + s.logger.Fatal(err, "unable to create controller", "controller", controller.ResticRepo) + } + if _, ok := enabledRuntimeControllers[controller.ServerStatusRequest]; ok { r := controller.ServerStatusRequestReconciler{ Scheme: s.mgr.GetScheme(), diff --git a/pkg/controller/restic_repository_controller.go b/pkg/controller/restic_repository_controller.go index cd4139640..9a1fa51e2 100644 --- a/pkg/controller/restic_repository_controller.go +++ b/pkg/controller/restic_repository_controller.go @@ -18,59 +18,46 @@ package controller import ( "context" - "encoding/json" "strings" "time" - jsonpatch "github.com/evanphx/json-patch" "github.com/pkg/errors" "github.com/sirupsen/logrus" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/clock" - "k8s.io/client-go/tools/cache" + + "sigs.k8s.io/cluster-api/util/patch" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" - velerov1client "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/typed/velero/v1" - velerov1informers "github.com/vmware-tanzu/velero/pkg/generated/informers/externalversions/velero/v1" - velerov1listers "github.com/vmware-tanzu/velero/pkg/generated/listers/velero/v1" "github.com/vmware-tanzu/velero/pkg/restic" - - "sigs.k8s.io/controller-runtime/pkg/client" + "github.com/vmware-tanzu/velero/pkg/util/kube" ) -type resticRepositoryController struct { - *genericController +const ( + repoSyncPeriod = 5 * time.Minute +) - resticRepositoryClient velerov1client.ResticRepositoriesGetter - resticRepositoryLister velerov1listers.ResticRepositoryLister - kbClient client.Client - repositoryManager restic.RepositoryManager +type ResticRepoReconciler struct { + client.Client + namespace string + logger logrus.FieldLogger + clock clock.Clock defaultMaintenanceFrequency time.Duration - - clock clock.Clock + repositoryManager restic.RepositoryManager } -// NewResticRepositoryController creates a new restic repository controller. -func NewResticRepositoryController( - logger logrus.FieldLogger, - resticRepositoryInformer velerov1informers.ResticRepositoryInformer, - resticRepositoryClient velerov1client.ResticRepositoriesGetter, - kbClient client.Client, - repositoryManager restic.RepositoryManager, - defaultMaintenanceFrequency time.Duration, -) Interface { - c := &resticRepositoryController{ - genericController: newGenericController(ResticRepo, logger), - resticRepositoryClient: resticRepositoryClient, - resticRepositoryLister: resticRepositoryInformer.Lister(), - kbClient: kbClient, - repositoryManager: repositoryManager, - defaultMaintenanceFrequency: defaultMaintenanceFrequency, - - clock: &clock.RealClock{}, +func NewResticRepoConciler(namespace string, logger logrus.FieldLogger, client client.Client, + defaultMaintenanceFrequency time.Duration, repositoryManager restic.RepositoryManager) *ResticRepoReconciler { + c := &ResticRepoReconciler{ + client, + namespace, + logger, + clock.RealClock{}, + defaultMaintenanceFrequency, + repositoryManager, } if c.defaultMaintenanceFrequency <= 0 { @@ -78,124 +65,106 @@ func NewResticRepositoryController( c.defaultMaintenanceFrequency = restic.DefaultMaintenanceFrequency } - c.syncHandler = c.processQueueItem - - resticRepositoryInformer.Informer().AddEventHandler( - cache.ResourceEventHandlerFuncs{ - AddFunc: c.enqueue, - }, - ) - - c.resyncPeriod = 5 * time.Minute - c.resyncFunc = c.enqueueAllRepositories - return c } -// enqueueAllRepositories lists all restic repositories from cache and enqueues all -// of them so we can check each one for maintenance. -func (c *resticRepositoryController) enqueueAllRepositories() { - c.logger.Debug("resticRepositoryController.enqueueAllRepositories") - - repos, err := c.resticRepositoryLister.List(labels.Everything()) - if err != nil { - c.logger.WithError(errors.WithStack(err)).Error("error listing restic repositories") - return - } - - for _, repo := range repos { - c.enqueue(repo) - } +func (r *ResticRepoReconciler) SetupWithManager(mgr ctrl.Manager) error { + s := kube.NewPeriodicalEnqueueSource(r.logger, mgr.GetClient(), &velerov1api.ResticRepositoryList{}, repoSyncPeriod) + return ctrl.NewControllerManagedBy(mgr). + For(&velerov1api.ResticRepository{}). + Watches(s, nil). + Complete(r) } -func (c *resticRepositoryController) processQueueItem(key string) error { - log := c.logger.WithField("key", key) - log.Debug("Running processQueueItem") +func (r *ResticRepoReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + log := r.logger.WithField("resticRepo", req.String()) + resticRepo := &velerov1api.ResticRepository{} + if err := r.Get(ctx, req.NamespacedName, resticRepo); err != nil { + if apierrors.IsNotFound(err) { + log.Warnf("restic repository %s in namespace %s is not found", req.Name, req.Namespace) + return ctrl.Result{}, nil + } + log.WithError(err).Error("error getting restic repository") + return ctrl.Result{}, err + } - ns, name, err := cache.SplitMetaNamespaceKey(key) + // Initialize the patch helper. + patchHelper, err := patch.NewHelper(resticRepo, r.Client) if err != nil { - log.WithError(errors.WithStack(err)).Error("error splitting queue key") - return nil + log.WithError(err).Error("Error getting a patch helper to update restic repository resource") + return ctrl.Result{}, errors.WithStack(err) } - log = c.logger.WithField("namespace", ns).WithField("name", name) + if resticRepo.Status.Phase == "" || resticRepo.Status.Phase == velerov1api.ResticRepositoryPhaseNew { + if err = r.initializeRepo(ctx, resticRepo, log, patchHelper); err != nil { + log.WithError(err).Error("error initialize repository") + return ctrl.Result{}, errors.WithStack(err) + } - req, err := c.resticRepositoryLister.ResticRepositories(ns).Get(name) - if apierrors.IsNotFound(err) { - log.Debug("Unable to find ResticRepository") - return nil - } - if err != nil { - return errors.Wrap(err, "error getting ResticRepository") - } - - // Don't mutate the shared cache - reqCopy := req.DeepCopy() - - if req.Status.Phase == "" || req.Status.Phase == velerov1api.ResticRepositoryPhaseNew { - return c.initializeRepo(reqCopy, log) + return ctrl.Result{}, nil } // If the repository is ready or not-ready, check it for stale locks, but if // this fails for any reason, it's non-critical so we still continue on to the // rest of the "process" logic. log.Debug("Checking repository for stale locks") - if err := c.repositoryManager.UnlockRepo(reqCopy); err != nil { + if err := r.repositoryManager.UnlockRepo(resticRepo); err != nil { log.WithError(err).Error("Error checking repository for stale locks") } - switch req.Status.Phase { + switch resticRepo.Status.Phase { case velerov1api.ResticRepositoryPhaseReady: - return c.runMaintenanceIfDue(reqCopy, log) + return ctrl.Result{}, r.runMaintenanceIfDue(ctx, resticRepo, patchHelper, log) case velerov1api.ResticRepositoryPhaseNotReady: - return c.checkNotReadyRepo(reqCopy, log) + return ctrl.Result{}, r.checkNotReadyRepo(ctx, resticRepo, patchHelper, log) } - return nil + return ctrl.Result{}, nil } -func (c *resticRepositoryController) initializeRepo(req *velerov1api.ResticRepository, log logrus.FieldLogger) error { +func (r *ResticRepoReconciler) initializeRepo(ctx context.Context, req *velerov1api.ResticRepository, log logrus.FieldLogger, patchHelper *patch.Helper) error { log.Info("Initializing restic repository") // confirm the repo's BackupStorageLocation is valid loc := &velerov1api.BackupStorageLocation{} - if err := c.kbClient.Get(context.Background(), client.ObjectKey{ + + if err := r.Get(context.Background(), client.ObjectKey{ Namespace: req.Namespace, Name: req.Spec.BackupStorageLocation, }, loc); err != nil { - return c.patchResticRepository(req, repoNotReady(err.Error())) + return r.patchResticRepository(ctx, req, patchHelper, log, repoNotReady(err.Error())) } repoIdentifier, err := restic.GetRepoIdentifier(loc, req.Spec.VolumeNamespace) if err != nil { - return c.patchResticRepository(req, func(r *velerov1api.ResticRepository) { - r.Status.Message = err.Error() - r.Status.Phase = velerov1api.ResticRepositoryPhaseNotReady + return r.patchResticRepository(ctx, req, patchHelper, log, func(rr *velerov1api.ResticRepository) { + rr.Status.Message = err.Error() + rr.Status.Phase = velerov1api.ResticRepositoryPhaseNotReady - if r.Spec.MaintenanceFrequency.Duration <= 0 { - r.Spec.MaintenanceFrequency = metav1.Duration{Duration: c.defaultMaintenanceFrequency} + if rr.Spec.MaintenanceFrequency.Duration <= 0 { + rr.Spec.MaintenanceFrequency = metav1.Duration{Duration: r.defaultMaintenanceFrequency} } }) } // defaulting - if the patch fails, return an error so the item is returned to the queue - if err := c.patchResticRepository(req, func(r *velerov1api.ResticRepository) { - r.Spec.ResticIdentifier = repoIdentifier + if err := r.patchResticRepository(ctx, req, patchHelper, log, func(rr *velerov1api.ResticRepository) { + rr.Spec.ResticIdentifier = repoIdentifier - if r.Spec.MaintenanceFrequency.Duration <= 0 { - r.Spec.MaintenanceFrequency = metav1.Duration{Duration: c.defaultMaintenanceFrequency} + if rr.Spec.MaintenanceFrequency.Duration <= 0 { + rr.Spec.MaintenanceFrequency = metav1.Duration{Duration: r.defaultMaintenanceFrequency} } }); err != nil { return err } - if err := ensureRepo(req, c.repositoryManager); err != nil { - return c.patchResticRepository(req, repoNotReady(err.Error())) + if err := ensureRepo(req, r.repositoryManager); err != nil { + return r.patchResticRepository(ctx, req, patchHelper, log, repoNotReady(err.Error())) } - return c.patchResticRepository(req, func(req *velerov1api.ResticRepository) { - req.Status.Phase = velerov1api.ResticRepositoryPhaseReady - req.Status.LastMaintenanceTime = &metav1.Time{Time: time.Now()} + return r.patchResticRepository(ctx, req, patchHelper, log, func(rr *velerov1api.ResticRepository) { + rr.Status.Phase = velerov1api.ResticRepositoryPhaseReady + rr.Status.LastMaintenanceTime = &metav1.Time{Time: time.Now()} }) } @@ -218,10 +187,10 @@ func ensureRepo(repo *velerov1api.ResticRepository, repoManager restic.Repositor return nil } -func (c *resticRepositoryController) runMaintenanceIfDue(req *velerov1api.ResticRepository, log logrus.FieldLogger) error { +func (r *ResticRepoReconciler) runMaintenanceIfDue(ctx context.Context, req *velerov1api.ResticRepository, patchHelper *patch.Helper, log logrus.FieldLogger) error { log.Debug("resticRepositoryController.runMaintenanceIfDue") - now := c.clock.Now() + now := r.clock.Now() if !dueForMaintenance(req, now) { log.Debug("not due for maintenance") @@ -233,17 +202,15 @@ func (c *resticRepositoryController) runMaintenanceIfDue(req *velerov1api.Restic // prune failures should be displayed in the `.status.message` field but // should not cause the repo to move to `NotReady`. log.Debug("Pruning repo") - if err := c.repositoryManager.PruneRepo(req); err != nil { + if err := r.repositoryManager.PruneRepo(req); err != nil { log.WithError(err).Warn("error pruning repository") - if patchErr := c.patchResticRepository(req, func(r *velerov1api.ResticRepository) { - r.Status.Message = err.Error() - }); patchErr != nil { + if patchErr := patchHelper.Patch(ctx, req); patchErr != nil { + req.Status.Message = err.Error() return patchErr } } - - return c.patchResticRepository(req, func(req *velerov1api.ResticRepository) { - req.Status.LastMaintenanceTime = &metav1.Time{Time: now} + return r.patchResticRepository(ctx, req, patchHelper, log, func(rr *velerov1api.ResticRepository) { + rr.Status.LastMaintenanceTime = &metav1.Time{Time: now} }) } @@ -251,7 +218,7 @@ func dueForMaintenance(req *velerov1api.ResticRepository, now time.Time) bool { return req.Status.LastMaintenanceTime == nil || req.Status.LastMaintenanceTime.Add(req.Spec.MaintenanceFrequency.Duration).Before(now) } -func (c *resticRepositoryController) checkNotReadyRepo(req *velerov1api.ResticRepository, log logrus.FieldLogger) error { +func (r *ResticRepoReconciler) checkNotReadyRepo(ctx context.Context, req *velerov1api.ResticRepository, patchHelper *patch.Helper, log logrus.FieldLogger) error { // no identifier: can't possibly be ready, so just return if req.Spec.ResticIdentifier == "" { return nil @@ -261,11 +228,10 @@ func (c *resticRepositoryController) checkNotReadyRepo(req *velerov1api.ResticRe // we need to ensure it (first check, if check fails, attempt to init) // because we don't know if it's been successfully initialized yet. - if err := ensureRepo(req, c.repositoryManager); err != nil { - return c.patchResticRepository(req, repoNotReady(err.Error())) + if err := ensureRepo(req, r.repositoryManager); err != nil { + return r.patchResticRepository(ctx, req, patchHelper, log, repoNotReady(err.Error())) } - - return c.patchResticRepository(req, repoReady()) + return r.patchResticRepository(ctx, req, patchHelper, log, repoReady()) } func repoNotReady(msg string) func(*velerov1api.ResticRepository) { @@ -285,37 +251,11 @@ func repoReady() func(*velerov1api.ResticRepository) { // patchResticRepository mutates req with the provided mutate function, and patches it // through the Kube API. After executing this function, req will be updated with both // the mutation and the results of the Patch() API call. -func (c *resticRepositoryController) patchResticRepository(req *velerov1api.ResticRepository, mutate func(*velerov1api.ResticRepository)) error { - // Record original json - oldData, err := json.Marshal(req) - if err != nil { - return errors.Wrap(err, "error marshalling original ResticRepository") - } - +func (r *ResticRepoReconciler) patchResticRepository(ctx context.Context, req *velerov1api.ResticRepository, patchHelper *patch.Helper, log logrus.FieldLogger, mutate func(*velerov1api.ResticRepository)) error { mutate(req) - - // Record new json - newData, err := json.Marshal(req) - if err != nil { - return errors.Wrap(err, "error marshalling updated ResticRepository") + if err := patchHelper.Patch(ctx, req); err != nil { + log.WithError(err).Errorf("error updating restic repository resource %s in namespace %s with err %s", req.Name, req.Namespace, err.Error()) + return err } - - patchBytes, err := jsonpatch.CreateMergePatch(oldData, newData) - if err != nil { - return errors.Wrap(err, "error creating json merge patch for ResticRepository") - } - - // empty patch: don't apply - if string(patchBytes) == "{}" { - return nil - } - - // patch, and if successful, update req - var patched *velerov1api.ResticRepository - if patched, err = c.resticRepositoryClient.ResticRepositories(req.Namespace).Patch(context.TODO(), req.Name, types.MergePatchType, patchBytes, metav1.PatchOptions{}); err != nil { - return errors.Wrap(err, "error patching ResticRepository") - } - req = patched - return nil } diff --git a/pkg/controller/restic_repository_controller_test.go b/pkg/controller/restic_repository_controller_test.go new file mode 100644 index 000000000..ba394a6e3 --- /dev/null +++ b/pkg/controller/restic_repository_controller_test.go @@ -0,0 +1,198 @@ +/* +Copyright The Velero Contributors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller + +import ( + "context" + "testing" + "time" + + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/cluster-api/util/patch" + ctrl "sigs.k8s.io/controller-runtime" + + velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" + resticmokes "github.com/vmware-tanzu/velero/pkg/restic/mocks" + velerotest "github.com/vmware-tanzu/velero/pkg/test" +) + +const defaultMaintenanceFrequency = 10 * time.Minute + +func mockResticRepoReconciler(t *testing.T, rr *velerov1api.ResticRepository, mockOn string, arg interface{}, ret interface{}) *ResticRepoReconciler { + mgr := &resticmokes.RepositoryManager{} + if mockOn != "" { + mgr.On(mockOn, arg).Return(ret) + } + return NewResticRepoConciler( + velerov1api.DefaultNamespace, + velerotest.NewLogger(), + velerotest.NewFakeControllerRuntimeClient(t), + defaultMaintenanceFrequency, + mgr, + ) +} + +func mockResticRepositoryCR() *velerov1api.ResticRepository { + return &velerov1api.ResticRepository{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: velerov1api.DefaultNamespace, + Name: "repo", + }, + Spec: velerov1api.ResticRepositorySpec{ + MaintenanceFrequency: metav1.Duration{defaultMaintenanceFrequency}, + }, + } + +} + +func TestPatchResticRepository(t *testing.T) { + rr := mockResticRepositoryCR() + reconciler := mockResticRepoReconciler(t, rr, "", nil, nil) + err := reconciler.Client.Create(context.TODO(), rr) + assert.NoError(t, err) + patchHelper, err := patch.NewHelper(rr, reconciler.Client) + assert.NoError(t, err) + err = reconciler.patchResticRepository(context.Background(), rr, patchHelper, reconciler.logger, repoReady()) + assert.NoError(t, err) + assert.Equal(t, rr.Status.Phase, velerov1api.ResticRepositoryPhaseReady) + err = reconciler.patchResticRepository(context.Background(), rr, patchHelper, reconciler.logger, repoNotReady("not ready")) + assert.NoError(t, err) + assert.NotEqual(t, rr.Status.Phase, velerov1api.ResticRepositoryPhaseReady) +} + +func TestCheckNotReadyRepo(t *testing.T) { + rr := mockResticRepositoryCR() + reconciler := mockResticRepoReconciler(t, rr, "ConnectToRepo", rr, nil) + err := reconciler.Client.Create(context.TODO(), rr) + assert.NoError(t, err) + patchHelper, err := patch.NewHelper(rr, reconciler.Client) + assert.NoError(t, err) + err = reconciler.checkNotReadyRepo(context.TODO(), rr, patchHelper, reconciler.logger) + assert.NoError(t, err) + assert.Equal(t, rr.Status.Phase, velerov1api.ResticRepositoryPhase("")) + rr.Spec.ResticIdentifier = "s3:test.amazonaws.com/bucket/restic" + err = reconciler.checkNotReadyRepo(context.TODO(), rr, patchHelper, reconciler.logger) + assert.NoError(t, err) + assert.Equal(t, rr.Status.Phase, velerov1api.ResticRepositoryPhaseReady) +} + +func TestRunMaintenanceIfDue(t *testing.T) { + rr := mockResticRepositoryCR() + reconciler := mockResticRepoReconciler(t, rr, "PruneRepo", rr, nil) + err := reconciler.Client.Create(context.TODO(), rr) + assert.NoError(t, err) + patchHelper, err := patch.NewHelper(rr, reconciler.Client) + assert.NoError(t, err) + lastTm := rr.Status.LastMaintenanceTime + err = reconciler.runMaintenanceIfDue(context.TODO(), rr, patchHelper, reconciler.logger) + assert.NoError(t, err) + assert.NotEqual(t, rr.Status.LastMaintenanceTime, lastTm) + + rr.Status.LastMaintenanceTime = &metav1.Time{Time: time.Now()} + lastTm = rr.Status.LastMaintenanceTime + err = reconciler.runMaintenanceIfDue(context.TODO(), rr, patchHelper, reconciler.logger) + assert.NoError(t, err) + assert.Equal(t, rr.Status.LastMaintenanceTime, lastTm) +} + +func TestInitializeRepo(t *testing.T) { + rr := mockResticRepositoryCR() + rr.Spec.BackupStorageLocation = "default" + reconciler := mockResticRepoReconciler(t, rr, "ConnectToRepo", rr, nil) + err := reconciler.Client.Create(context.TODO(), rr) + assert.NoError(t, err) + patchHelper, err := patch.NewHelper(rr, reconciler.Client) + assert.NoError(t, err) + locations := &velerov1api.BackupStorageLocation{ + Spec: velerov1api.BackupStorageLocationSpec{ + Config: map[string]string{"resticRepoPrefix": "s3:test.amazonaws.com/bucket/restic"}, + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: velerov1api.DefaultNamespace, + Name: rr.Spec.BackupStorageLocation, + }, + } + + err = reconciler.Client.Create(context.TODO(), locations) + assert.NoError(t, err) + err = reconciler.initializeRepo(context.TODO(), rr, reconciler.logger, patchHelper) + assert.NoError(t, err) + assert.Equal(t, rr.Status.Phase, velerov1api.ResticRepositoryPhaseReady) +} + +func TestResticRepoReconcile(t *testing.T) { + tests := []struct { + name string + repo *velerov1api.ResticRepository + expectNil bool + }{ + { + name: "test on api server not found", + repo: &velerov1api.ResticRepository{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: velerov1api.DefaultNamespace, + Name: "unknown", + }, + Spec: velerov1api.ResticRepositorySpec{ + MaintenanceFrequency: metav1.Duration{defaultMaintenanceFrequency}, + }, + }, + expectNil: true, + }, + { + name: "test on initialize repo", + repo: &velerov1api.ResticRepository{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: velerov1api.DefaultNamespace, + Name: "repo", + }, + Spec: velerov1api.ResticRepositorySpec{ + MaintenanceFrequency: metav1.Duration{defaultMaintenanceFrequency}, + }, + }, + expectNil: true, + }, + { + name: "test on repo with new phase", + repo: &velerov1api.ResticRepository{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: velerov1api.DefaultNamespace, + Name: "repo", + }, + Spec: velerov1api.ResticRepositorySpec{ + MaintenanceFrequency: metav1.Duration{defaultMaintenanceFrequency}, + }, + Status: velerov1api.ResticRepositoryStatus{ + Phase: velerov1api.ResticRepositoryPhaseNew, + }, + }, + expectNil: true, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + reconciler := mockResticRepoReconciler(t, test.repo, "", test.repo, nil) + err := reconciler.Client.Create(context.TODO(), test.repo) + assert.NoError(t, err) + _, err = reconciler.Reconcile(context.TODO(), ctrl.Request{NamespacedName: types.NamespacedName{Namespace: test.repo.Namespace, Name: test.repo.Name}}) + if test.expectNil { + assert.NoError(t, err) + } else { + assert.Error(t, err) + } + }) + } +} diff --git a/pkg/restic/mocks/repository_manager.go b/pkg/restic/mocks/repository_manager.go new file mode 100644 index 000000000..b164cb3e0 --- /dev/null +++ b/pkg/restic/mocks/repository_manager.go @@ -0,0 +1,147 @@ +/* +Copyright the Velero contributors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License.*/ +// Code generated by mockery v2.10.2. DO NOT EDIT. + +package mocks + +import ( + context "context" + + mock "github.com/stretchr/testify/mock" + restic "github.com/vmware-tanzu/velero/pkg/restic" + + v1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" +) + +// RepositoryManager is an autogenerated mock type for the RepositoryManager type +type RepositoryManager struct { + mock.Mock +} + +// ConnectToRepo provides a mock function with given fields: repo +func (_m *RepositoryManager) ConnectToRepo(repo *v1.ResticRepository) error { + ret := _m.Called(repo) + + var r0 error + if rf, ok := ret.Get(0).(func(*v1.ResticRepository) error); ok { + r0 = rf(repo) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Forget provides a mock function with given fields: _a0, _a1 +func (_m *RepositoryManager) Forget(_a0 context.Context, _a1 restic.SnapshotIdentifier) error { + ret := _m.Called(_a0, _a1) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, restic.SnapshotIdentifier) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// InitRepo provides a mock function with given fields: repo +func (_m *RepositoryManager) InitRepo(repo *v1.ResticRepository) error { + ret := _m.Called(repo) + + var r0 error + if rf, ok := ret.Get(0).(func(*v1.ResticRepository) error); ok { + r0 = rf(repo) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// NewBackupper provides a mock function with given fields: _a0, _a1 +func (_m *RepositoryManager) NewBackupper(_a0 context.Context, _a1 *v1.Backup) (restic.Backupper, error) { + ret := _m.Called(_a0, _a1) + + var r0 restic.Backupper + if rf, ok := ret.Get(0).(func(context.Context, *v1.Backup) restic.Backupper); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(restic.Backupper) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *v1.Backup) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NewRestorer provides a mock function with given fields: _a0, _a1 +func (_m *RepositoryManager) NewRestorer(_a0 context.Context, _a1 *v1.Restore) (restic.Restorer, error) { + ret := _m.Called(_a0, _a1) + + var r0 restic.Restorer + if rf, ok := ret.Get(0).(func(context.Context, *v1.Restore) restic.Restorer); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(restic.Restorer) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *v1.Restore) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PruneRepo provides a mock function with given fields: repo +func (_m *RepositoryManager) PruneRepo(repo *v1.ResticRepository) error { + ret := _m.Called(repo) + + var r0 error + if rf, ok := ret.Get(0).(func(*v1.ResticRepository) error); ok { + r0 = rf(repo) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// UnlockRepo provides a mock function with given fields: repo +func (_m *RepositoryManager) UnlockRepo(repo *v1.ResticRepository) error { + ret := _m.Called(repo) + + var r0 error + if rf, ok := ret.Get(0).(func(*v1.ResticRepository) error); ok { + r0 = rf(repo) + } else { + r0 = ret.Error(0) + } + + return r0 +}