diff --git a/changelogs/unreleased/7000-qiuming-best b/changelogs/unreleased/7000-qiuming-best new file mode 100644 index 000000000..61b3ade5d --- /dev/null +++ b/changelogs/unreleased/7000-qiuming-best @@ -0,0 +1 @@ +Make Kopia file parallelism configurable diff --git a/config/crd/v1/bases/velero.io_backups.yaml b/config/crd/v1/bases/velero.io_backups.yaml index 5314b862c..9099eb13f 100644 --- a/config/crd/v1/bases/velero.io_backups.yaml +++ b/config/crd/v1/bases/velero.io_backups.yaml @@ -477,6 +477,15 @@ spec: description: TTL is a time.Duration-parseable string describing how long the Backup should be retained for. type: string + uploaderConfig: + description: UploaderConfig specifies the configuration for the uploader. + nullable: true + properties: + parallelFilesUpload: + description: ParallelFilesUpload is the number of files parallel + uploads to perform when using the uploader. + type: integer + type: object volumeSnapshotLocations: description: VolumeSnapshotLocations is a list containing names of VolumeSnapshotLocations associated with this backup. diff --git a/config/crd/v1/bases/velero.io_podvolumebackups.yaml b/config/crd/v1/bases/velero.io_podvolumebackups.yaml index 3922fdc07..a642f3949 100644 --- a/config/crd/v1/bases/velero.io_podvolumebackups.yaml +++ b/config/crd/v1/bases/velero.io_podvolumebackups.yaml @@ -121,6 +121,14 @@ spec: description: Tags are a map of key-value pairs that should be applied to the volume backup as tags. type: object + uploaderConfig: + description: UploaderConfig specifies the configuration for the uploader. + properties: + parallelFilesUpload: + description: ParallelFilesUpload is the number of files parallel + uploads to perform when using the uploader. + type: integer + type: object uploaderType: description: UploaderType is the type of the uploader to handle the data transfer. diff --git a/config/crd/v1/bases/velero.io_schedules.yaml b/config/crd/v1/bases/velero.io_schedules.yaml index a334ee6ce..0cf3cbe52 100644 --- a/config/crd/v1/bases/velero.io_schedules.yaml +++ b/config/crd/v1/bases/velero.io_schedules.yaml @@ -514,6 +514,16 @@ spec: description: TTL is a time.Duration-parseable string describing how long the Backup should be retained for. type: string + uploaderConfig: + description: UploaderConfig specifies the configuration for the + uploader. + nullable: true + properties: + parallelFilesUpload: + description: ParallelFilesUpload is the number of files parallel + uploads to perform when using the uploader. + type: integer + type: object volumeSnapshotLocations: description: VolumeSnapshotLocations is a list containing names of VolumeSnapshotLocations associated with this backup. diff --git a/config/crd/v1/crds/crds.go b/config/crd/v1/crds/crds.go index f0814a70a..fff600dc1 100644 --- a/config/crd/v1/crds/crds.go +++ b/config/crd/v1/crds/crds.go @@ -30,14 +30,14 @@ import ( var rawCRDs = [][]byte{ []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xb4VAo\xe46\x0f\xbdϯ \xf6;\xec\xe5\xb3g\xb7\xbd\x14\xbem\xd3\x16\b\x9a\x04A\x12\xe4Nۜ\x19mdI\x95\xa8I\xa7E\xff{A\xc9\xcexl'\xb3Y\xa0\xbaY\xa2\x1e\xc9G>ZEQ\xacЩG\xf2AYS\x01:E\x7f2\x19\xf9\n\xe5\xd3O\xa1Tv\xbd\xff\xbczR\xa6\xad\xe0\"\x06\xb6\xdd\x1d\x05\x1b}C\xbf\xd0F\x19\xc5ʚUG\x8c-2V+\x004\xc62\xcav\x90O\x80\xc6\x1a\xf6Vk\xf2ŖL\xf9\x14k\xaa\xa3\xd2-\xf9\x04>\xb8\xde\x7f*?\xffP~Z\x01\x18쨂\x1a\x9b\xa7\xe8<9\x1b\x14[\xaf(\x94{\xd2\xe4m\xa9\xec*8j\x04}\xebmt\x15\x1c\x0f\xf2\xed\xdes\x8e\xfa\xe7\x04t7\x00\x1dґV\x81\x7f_<\xbeR\x81\x93\x89\xd3ѣ^\n$\x1d\ae\xb6Q\xa3\x9f\x19\x88\x83\xd0XG\x15\xdcH,\x0e\x1bjW\x00}\xa6)\xb6\x02\xb0m\x13w\xa8o\xbd2L\xfe\xc2\xea\xd8\r\x9c\x15\xf05Xs\x8b\xbc\xab\xa0\x1c\xd8-\x1bO\x89\xd8\a\xd5Q`\xec\\\xb2\x1d\b\xfb\xb2\xa5\xfe\x9b\x0f\xe2\xbcE\xa69\x980W\x1ec}88:A9\x12\x01\xa3\xb3\x8c\x18\xd8+\xb3]\x1d\x8d\xf7\x9f3\x15͎:\xacz[\xeb\xc8|\xb9\xbd|\xfc\xf1\xfed\x1b\xc0y\xebȳ\x1aʓר\xfdF\xbb\x00-\x85\xc6+ǩ9>\n`\xb6\x82V\xfa\x8e\x02\xf0\x8e\x06N\xa9\xedc\x00\xbb\x01ީ\x00\x9e\x9c\xa7@&w\xe2\t0\x88\x11\x1a\xb0\xf5Wj\xb8\x84{\xf2\x02\x03ag\xa3n\xa5]\xf7\xe4\x19<5vk\xd4_/\xd8\x01\xd8&\xa7\x1a\x99\xfa\x1e9\xaeTC\x83\x1a\xf6\xa8#\xfd\x1fд\xd0\xe1\x01<\x89\x17\x88f\x84\x97LB\t\xd7\xd6\x13(\xb3\xb1\x15\xec\x98]\xa8\xd6\xeb\xad\xe2Av\x8d\xed\xbah\x14\x1f\xd6IA\xaa\x8el}X\xb7\xb4'\xbd\x0ej[\xa0ov\x8a\xa9\xe1\xe8i\x8dN\x15)t\x93\xa4Wv\xed\xff|/\xd4\xf0\xf1$\xd6Y-\xf3Jby\xa3\x02\xa2\x16P\x01\xb0\xbf\x9a\xb38\x12-[\xc2\xceݯ\xf7\x0f0\xb8NŘ\xb2\x9fx?^\f\xc7\x12\ba\xcal\xc8\xe7\"n\xbc\xed\x12&\x99\xd6Ye8}4Z\x91\x99\xd2\x1fb\xdd)\x96\xba\xff\x11)\xb0Ԫ\x84\x8b4\x8b\xa0&\x88N\xd4Жpi\xe0\x02;\xd2\x17\x18\xe8?/\x800\x1d\n!\xf6\xdbJ0\x1e\xa3S\xe3\xcc\xda\xe8`\x18\x81\xaf\xd4k:\xd6\xee\x1d5R>aP\xae\xaa\x8dj\x926`c=\xe0̾<\x81^\x96\xae\xac<\xfc\xee\xd9z\xdcҕ͘S\xa3\xc5\xd8&w\x86\xe0d\xb2d\x19Ӳ\xe1\f\x1b\x80w\xc8#\xfd2*\xf32\x06\x16\xf3y\xa3\b\xa9\x10(r6h\x1a\xfa-u\x94i\x0egr\xba^\xb8\")\xed\xec3\xd8\r\x93\x19\x83\xf6\xb1.dR\x13\xf8h\xde\x15\xec\xe90?\x13\xe6݉1(\xd3J\x1b\xf4\xd3T\x9c\f\xd4K]ɴ\xe0O\xff\x9b\xe3E&vsw\x05\xfdy\xf3\xf6_7\x7f~E\x88\xa0\x05ܒ\x1d͞\xaaRoN\xc0A\xc9\r\x93\xaft\t\x99\x05yP\xb2*oI\xf3\x83\xeb\xe2\x87s\xa8\xfe\x05{\xe3\vδ\xf9\xa9\xf5\xf2g\xa6\r\xfeP\xf2JQ^\x8f\x84\xef4\x13\x87\x8aS\x15\u07be\"Dg\xb2\x84[\xf2\xc9\x0eQ\xd2\f\xf2W\x84x\xacqȵG\xf8\xf4\xd6AȎPP\x87\v!\xb2\x04\xf1\xee~\xfb\xe5\xdf\x1e:\xaf\t\xc9Ag\x8a\x95\x06\xe7\xee\x10#L\x13J\xbeഈ\xf2T&\xe6H\rQP*\xd0 \x8c&\xe6\b$\xa3\xa5\xa9\x14\x10\xb9'?U;P\x02\f\xe8\x1a4!\x19\xaf\xb4\x01E\xb4\xa1\x06\b5\x84\x92R2a\b\x13İ\x02\xc8\x1f\xde\xddo\x89\xdc\xfd\x06\x99ф\x8a\x9cP\xadeƨ\x81\x9c\x9c$\xaf\np}\xff\xb8\xa9\xa1\x96J\x96\xa0\f\vtvOKxZo{\xd3{m)\xe0Z\x91\xdcJ\r\xb8ix*B\xee\x89f\xe7c\x8eL7\xd3E9\xea\x00&\xb6\x11\x15\x1e\xf9\ry\x00e\xc1\x10}\x94\x15ϭ\xb0\x9d@Y\x82e\xf2 \xd8?jؚ\x18\x89\x83rj\xc0\v@\xf30a@\t\xcaɉ\xf2\nn\x90$\x05=\x13\x05v\x14R\x89\x16\x93\x96r\x88\xfe؛G\xc3H+\xa98\xf31ԭ#зh᱈Z\x0f\x17-g\xceN,\xaf(G#JE\xe6\xe6Ck\xbcb\xc6x\x82\xc9\x03\x9c\x9d\x89\x0e\x98[Nt\xc2\x11)\xc0\xba\xa0\x85\x8d\xc1\x86McF\xc6=c\xd3\xdeQ\xebgH'\xa2\xaa\xe2\xa0\xfdPαkt\xc0\xcd(\xe8\x9a#.~\xe7t\a\x9ch\xe0\x90\x19\xa9\xe2\xe4\x98c\xb2{R\xf4\xda\b\x15#\x1a\xae\x1b\x104\x13\x9b\x00I0\xa8:\xb2\xec\xe8\xdc4+A\b\x87\xe4\x124\xaerZ\x96\x055\xd9\xf1\xc3W\xeby\xe9&\x97\x93H\x97~g\xe7\xbf\x06\x7f\xbek\x98g\xe0\x12\xdc\x14f\n\n\xb7\xd9\xfc\x88\xd4lޠG\xf5\xee\xd3\xfb\xd8nV\xf7I\x90\xbc\xc1D\xde\xf5\x90m\x0f\xed\x9d\xf2\xd4ixק\x8eo\\\x1a\xe1\x86P\xf2\x04g\xe7\xb1PA,s\xa8\x1dh$\xd2\x19\x12\a\xf3\x19(dOpF0>A1\xdb;U\x14\xdc\xf3\x04\xe7\x94f=\x02Z\x9c\x98\xf6\x89\x17KI\xfb\x02\t\x81\xfb\xd9\xe9\xc4#\x98l\n\xbah~r$]\x91\x84'\xd0\xfe\x82i\xd6lk%ꐱ\xaf\xb5c\x91]\x05GV&NԚ9\xdcJ\x90\xfb:\xdd\xf4\x85r\x96\xd7\x039\xb9ߊqo\xb8\xfb|\x92f+nȇ\xafL\xfb\x8c\xdf{\t\xfa\x934\xf8\xe6E\xc8\xe9\x10\xbf\x80\x98\xae#./\xe1Զ\xa5C;o\x95 \xdc\xeeٺ\b\xaff\x0f\xd3d+l\xdc\xe2\xe9\x81YH7ܴ}\xe8>E\xa511%\xa4X\xbb\xad\x97\xd8H\x8e؉ \xa5\xeapd\x88Z=\xe8\xc8^O\xfcy\xb4\x96\xc4\xf5wyUN3\xc8C^\x05\xb3\x81\xd4\xc0\x81e\xa4\x00u\x982\x1c\xed\xa7\xb4\xfa=\r\x85D\xad랅\x12\x96f\xda\xc3\xe3Uwt\xf3\xbb\xfb\xac\xed\xcaMh\x15\x98=\xdbt$\t8\xdet~Fhb\xd1\xff\x98\xa5.\xcds,Ӡ\xfc~\x81\xc6_\xc0\x8b\xa1\xedw\x889\vYPLN\xfc\xb75s(\xd0\xffCJ\xcaT\xc2\x1a~\x87\xe5\x18\x1c:}\xfd.V{\x18;\x02\xd3\xc4\xf2\xf7D\xf90\xbd\x1c\x99\x9c\xb4\xba\x05\xb83\xe4r?\xf0Xn\xc8\xf3QjgS1)2\v\x92i\xb2z\x82\xb3OƵ\xf5\xc0j+V\xce\xc0/V7\xb5\xb7 \x05?\x93\x15\xf6]}\x8b\x13\x94(\x89\x89;\xae\x9f\xea\xf2\x93uA˵\x97^#\v\x96\x8d\xf6\xc3r\x99T\x17\xdbƠ\xc1\x83\xb0\x1d\xeb\x1a\x11\xeb\x1eO\xcd6I~K\xa9#\x99\xef\x11T\xee\xa56nG\xb2\xe3\xce.\xd9\xfd\"N\xf6\xfc\xae\x17\xa1{W\xa5#U\xa8\xbf\xb0겷Qk\xb9\xad\xa75\xb3\xcb\x19\xf8\x9d4\a\xd4\x06d\xabf\xe5;=\xbcr9\v\x1c\x84f\xe8\x94\xcc\xc2-\x95\xcc@G\xb3\xc5͓\xa0\xe5g6\x17\xeb\x8dE\xea\x02\x1fW\xdc0\xbd\x99\x19\x9etG\xd6\x12ia\b\xf0\xe1kk\xd7\xd3*\r\xfb\xf7\x9c\xf0-ŋ\xe0Z/\nگ\xe2IB\xf1\xce\xf5\f\xcb\xc4\x03r!\x85:T\xa8\"\xd2=O/H߃y/\x98\xd8\xe2\x00\xe4\xed\xd5݁Z\xb9\xc6j9bO\x8f\xe4\xbeoC\xf4\xfa\x85\x18)\xe6\x88=\xa5\xc4\x1d\x7f\x05\x1d\xce\r\xf7ǭ\x83\x99\bRH\xd3ކ\xb0pK\x99\xbf\xd6dϔ6mDS\x85\"^+\x12{\x96F\\\xe2\x83R\x17\x05\\\xbf\xba\x9e\xad\r\xb0\xa3|\x0e\xb5P\xa3\xc5\x13\xb1\a\x93I@؞0C@d\xb2\x12\xb8mc\x97:\x0e\xe1X\xe0\x14t2\xc9\xd2\x14\x84}@TE\x1a\x01\xd6(uLL\xeeﴛ\x7f\xa4,\x96\x81\x1e>\v\xd9f\xc6J\xc6bO\x87m\xa1v\xac]\xd4VЯ\xac\xa8\nB\vK\xfa\xd4pi\xef*\xce:\x1c\xaf\xeb\xce\x10.\x9a\x11#\xed\xa2*9\x98\xd4\x15\xe9*\xcc\xec2\xd1,\x87\xda0{)\x90\x82P\xb2\xa7\x8c\x8f\x94\xbb\f\x9fE\xb4]\x12\xa3xeq\xbd\xe0#m\xf05\x92\"a\x037\xd1ɜ\xd6֥Jw\x15\xef\x15\xa4\xb9gs\x9b\xd9\xc1=+\x15\x93X\xa7we\x0f͋\x18\x15\xe7\x1f.\xda\xe0\xf9\xe1\xa2\xcd3ś\xdfP/\x1f\x06\xbd\xa8^~;\xd9\xf9J\xf5\xf2\x1eþ\xd7}\xa5j\xf90\xffe\xd5\xf27\xbeT\xa3\x00\x1a\xb6\xe7].>\x1f\x1b\xb27\xda\x00\xf0\xef\\\x7f;\xa8\x0f\xbb\x8c\xf1/^m?\xc2\xfc\xc4\xc2\xf8՟V\xdf\x1f\xa5\x17\xd3v\x94\x9a\x032E&\x15\x8e\xf9ڸ\xb2]\xdc\xd5-\xa4\xfb>\x85s\xa94\xa6V\xccO\xd1k\xa8eZ\x04\xfb^\x17\xb3\x81\xe2\xd7\xd2ۊ\xb4\x13\x9d\xdbH\x97\xb93\x9d\x91\xf9\xe0&\x80>\x8b쨤\x90\x95\xf6\xfb\x06\x16\xfa;ܾ\xf0\xa9P,\x03KT\xb0o\xc9QV\x91\x8a\xed\t\xda\xcd\xd4\xef\x8dW\xed\xf9\x1c5\x18zz\xbb\xe9\xfeb\xa4\xaf\xe1#\xcf\xcc\x1c#x>\x1fA`v]\x1c\xda\x05\xf9a\xc1\xf9\x03\xe7}A\"R\x11\xc1\xf8\x98\xc1\xaaO\xe5wLӯ\xa5\xdb$Zl\xf9\xa778Ҫ\xfc.\xae\xed\xeb\xd6\xee\x8d8\x81K\x93\xd9\xe9G\x18ҫ\xf7\xa6\xcb\xed\x96\xd4\xec\xf5+\xf2F\x81\xceW\xea\xa5\xecM\xcdT\xe5]P\x8b\x97X\x87\xfdͩ\xf7\x94j\xbb\x8bj\xecfK\x95\x13+\xeb\xba5s\xd3 \x17\xd4\xd3%\x11g\xbevnqŜ\xafP\x9b\x9cGr\x9d\\\xa4\x02n\x12\xf0hu\xdcT\xdd\xdb̾\xf7\xb0&.\xbd\xdam\x124V\xc2\xcd\u05f8]\xaf\x92\xfd\x1aQ\xf6\xb8\xaa\x99\xadS\x9b\x8d§\xf1\x9b\xadD[R\x7f6K\xb1\vk\xcd\xeaZ\xb2\x91q\x97V\x98u+\xc8F\x80\xa6ԕ\x8dԍ\x8d@\x9c\xac&K\xad\x16\x1b\x81=cv'\xa5d\xf2\xc7%Ub\xf1KTȬ5俗\xfc]J\x06\xa9:\xce\xe5\\@\xf3k\xaf\xb9\xe5|𱦝\u0558\x9f\xca\xccq\xb9\xb3ZTܰ\x92cz\xf1\xc4\xf2h\xccn\x8ep\xae/\x86\xf8M\xe2qMw\x99\t\xf9\xf5s-̛\x9e\xcbM5y\x06\xce\t\x8d\x89\xe2`晻\a(\x93k\xb0\x16\xc2.O\x7f兿.\xe8\xc6\xc9;\x9eH\x8de`\xcc\x11\n\ve\xfcړQU>\xedN:\xcf\x17\xdf\xfd\xbd\x02u&x=K\xed_̜\x87r\xcbR\xdbX((\n\xafm\xdc\xedS=7\xbbY\x9e\xe4\x9dp\x06/\n\xb6\x87#±\x1a\x82\u05fc\xb6\xca\xd0F\r#M\xe3\x1b\xb1\xb2\xee\x1d\xf9}\xceSM=L\xf4\xb2\x81\xc6\xf2Pc\xd6ȿH\xb8qy\xc01\x012\xf5pPZB|\xf60\xd0K\x05\x1es\xa1G\xb2ϕv\xd8\xe7%\x0e\xf9,8ܳ \x04Y\x16\x84$\x93)\xe5\x10ϋ\x84\"/\x18\x8c\xbcD8rY@2\x03\xb2w8'\xe5\xd8MR\xb1Gr\xbe3\xa5Xc>%9}\x9c&\xe1\x18MB\xb2r\x0eӄ\xe32ˎ\xc9$\xd0\xf0\x85B\x95\x17\nV^\"\\yـe6d\x99\x95\x9c\x99\x9f\x97\x1do\xb9x\xf3^\xaa\x1c\xd4d\xae#U4'\x85\xb2\x17_t\xc7\xec\xed\xfc\x87;\xe5l\xab\x8e+\x1b۰\xaeO\xbdg\xe4'&|\x1e\xd5\na\xcb\xeew\x120\x8d#\x12\xdf\xffo\xbc<\x7fۨ\xcb\xdah(\xa9\xc2\f\xeb\xee\xecJ+\xf4\x86|\xa0ٱ\a\xfd\x18\x8d+\xf6R\x15ԐU\x9d\xf2z\xe3\x80ۿW\x1bB>\xca:i߾IF\xb3\xa2\xe4g\x1b7D`\xae\xda .\x13\x88\xa8\xf0\x85\xf1\xef%gY\xc4ӊ^.\xe4\x1a\x0f\xae\x84\xc0+\x8f\xb2v껴\r\xe3\x8e\x16:e\xdd\xeb\x15\xf7\x92s\xf9\xbc0\x1c\xa7%\xfb\x0f\xbc\xa5y~\x0f\xe7\xdd\xfd\x16\x9b\x06I\xc1\u06dd\xeb\n\xa1\x1a\xe9\x1dX\x8b\xd9Lgl\xc5o\xf7\x1d\x88\x91J\xbb\xfaO\x94\xd6\xdab\xb3\xb1[\x97\\՟\xd54\xf7[\x87\xdd\x06\x85\x85\x8a3\x91X\xeba\x8eL\xe5\xeb\x92*svu\x0575\x0e\xe3\xfb8\xc1nN\xed\xb6\x8c\x9a\x97\xe1u\xbfQچ[\x7f1\x99w.\xbb\xa9\xd0>E/\xc1c\xfc(\xdf\xec!\xbe+\xe21\ue0ac\x91R\x91\xd7Ѣ\xa4\xab\xedbi\x7f\xb5\xed/\xf2\x04\uf8fbY\x1d\xf2<\xf4\x9aGʉ\x02Dw\xb9\xeb\xd4\xed\xa0x9\xe7e\xba(^\x1f\x14\x86\xf6\xd7w&\xceŷ\x8eL%\xdc\\\x1a\xe0\xea\xf8\xae\x8d]^\xf7_0\xb4\xaaU\x98wv|\xf0\x14\xb6\xae\xfa\x17\xdc\xfd\xe5\xfa5R\xdaHE\x0f\xf0\xb3tW/\xcfѠۺs\xef\xb6wyB\xcdbX\r\xb1P\xc0_\x02\xdd\x03֔\"\x0f\xae\xc1\xb5X.\xbc\xd5\xd7\x18>3\x99\xc7ǟ\xdd\x04\f+`\xf3\xber\xb9|\xab\xed4Xj\x86\x89\xb9N;\xfb\xdfc\xc4^\x10\xbcO\xb6ş\x16\xde\n\xb0\xdc\x19\xcb\xde\x16a\x7f\xea\\$\x1dH4'\xa2_\xe2\xbdZ\xfbK-&9\xd7#*\xa1cpZw\xe9\xe3\xce+\x1eW\xbe\ueb4bc\xce\xe4\xd8m\xe3x\xc3\xf6\xfc}\xe3\xee\"n\xffu\x01_4_)\xbc2\xd1_ҍW\f^t\xe5\xf8\xae\xae\v\xa9\xabN\xf4;cl\xa0\x1c\xd3\xdc\x11\xf4F\xfa\xd6\x06N\x1aʉ\xa8\x8a\x1d\xfa\xac1\x95Rw\xc1\x8a\x95\xc9R\x15\xe7\x80L0Α\x9a\t\x03\x87\xc1\xa6{l\xaew\xbe\xc6\xf9\x92\xb9\xd6}\xd3窫,\x03\xad\xf7\x15\xe7纾z\xc9\xc4c\xd6\xe5J\xa4\xf8H\x19\xbf\x88\x0e\xae\xe3\b\x11\xdc\xdcF\xf5h\x12\x9b}Q'\x88<,ށ)\xb0\x0f\x9e:XF\a\xcf\x02_k\xa5\r-\xe6nN\xbf\x1b\xf6\xc0\xcfZ\xa8\xbcU\x9dU_\xff\xfdLu\xc3\xe6\x98Oـs=\xd1\x05\xb5\xd0 'p\x02A\xa4\xc0\xaay\xbc\x8b\xd3}z\xa5\xdf'\x02\xb5\rŗ\xe5W%\x974\x0f\x06.D\x92\xfes\x1d\x8fh\xbe\xd5\t\xd4k=\x01\xb3\xbe\xd0=B\x84\xa1d\xba\xd0\xee\xd6\xfaF\xb0\x8e\x02M2\xfdQ]\x9bi\xd6\xd5\xf3\xc9J\xeb\xeea;\xd6sT\x82C\x83\x18\xff\x06\x1fN\xf8F%5\x9cY\xaa\x8a\x1a\xcelNAu\xd4Qdr\x8d\x82\xba\xfa4q\xad\xce\u07b8\x8c\x8d\x9c\a\x80Nj\xc2u\xfa\xee|Q\x01Z\xd3C\xb8j\xf9\xd9:`\a\x10\x80\x9b\x11\x91\xd9\xf8\xed\xdd\xe6\x027\xaf,R\xa4D\r\xa1C\x99\x86\xa9\x94h\xa5r\xea\xf3b\r\xba4{\x1a\xc5ԧ\xa2\xc3G\x0f\xdf\xf8\x8b\xd3\xd7{%\x8b\xb5\xe7\x05VW\xdc\xf8\xf4\x8ab\xd2\x06\xec\xe6\x18%9q\xdfT\xf27\x14\xa3\x18\x94%\bB\xb5\xc7'\xe1b\x89i\xb6N\xec\xa6jC\x95I\x8d\x83\x1e:\x8dgB \x84\x1c\xc7\xf7\xc1\xa7\x8f\xdc\x05\x1bw\xfe\x93b5\xe0\x1b\xa2\x99\b\xdf[t\xc9)'\n\xdaFF\nps-Z83\x88i:\x11L\x17\xfd\xdf7x9\xd56\xf1C\x8a\x17\xfc\xa5\u05fcw\x88\n?\xaeU7\xf1\x9ek\x84\x1e\x7f`{W˓Y\xac\xff\xf8\x7f~8\xea\x94\xe4e\xbd\x9et\xb0\xd0w\xaa=\xa5\x99Oi\xdds\xb0\x9e\x8f\x06\xe8\xfan\xaf\x179\xe9\xa7\xcb\xc2\xcekƜ\xe1S\xa0\u05c9\xc4N\x97E\x9b/\x16j^wv\xcf\x14??8\xb7\xc6\xfe\xe6\x9bEbM\x0f!\x12mF\xa6Qǟ\xb3\xd1f+\xd8\f8\x8e|-\xa8\x17\x80^)܌ځ\xc1KT\xa0ykm\xfb\x91\xfc\x9b\xff\r\x00\x00\xff\xff\x9a\xfbL\xe1\xa9x\x00\x00"), + []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xec=M\x93\xdb:rw\xff\n\x94r\xf0\xee\xd6H~N.)\u07fcc;Q\xbd\xf7\xec)\xcf<\xef%\x17\x88lIx\x03\x02\\\x00\xd4X\x9b\xca\x7fO\xa1\x01\xf0\x13$AY\xf3\xe2M\x99\x17{(\xa0\xd1\xe8n\xf4\x17\x1a\xe0z\xbd~AK\xf6\x05\x94fR\xbc!\xb4d\xf0Հ\xb0\x7f\xe9\xcd\xe3\xbf\xeb\r\x93\xafN\xaf_<2\x91\xbf!\xb7\x956\xb2\xf8\fZV*\x83w\xb0g\x82\x19&ŋ\x02\fͩ\xa1o^\x10B\x85\x90\x86\xda\xd7\xda\xfeIH&\x85Q\x92sP\xeb\x03\x88\xcdc\xb5\x83]\xc5x\x0e\n\x81\x87\xa1O?m^\xff\xeb\xe6\xa7\x17\x84\bZ\xc0\x1b\xb2\xa3\xd9cU\xea\xcd\t8(\xb9a\xf2\x85.!\xb3 \x0fJV\xe5\x1b\xd2\xfc\xe0\xba\xf8\xe1\x1c\xaa\x7f\xc5\xde\xf8\x823m~n\xbd\xfc\x85i\x83?\x94\xbcR\x94\xd7#\xe1;\xcdġ\xe2T\x85\xb7/\bљ,\xe1\r\xf9h\x87(i\x06\xf9\vB<\xd68\xe4\xda#|z\xed dG(\xa8Å\x10Y\x82x{\xb7\xfd\xf2o\xf7\x9dׄ\xe4\xa03\xc5J\x83sw\x88\x11\xa6\t%_pZDy*\x13s\xa4\x86((\x15h\x10F\x13s\x04\x92\xd1\xd2T\n\x88ܓ\x9f\xab\x1d(\x01\x06t\r\x9a\x90\x8cWڀ\"\xdaP\x03\x84\x1aBI)\x990\x84\tbX\x01\xe4Oo\xef\xb6D\xee~\x87\xcchBEN\xa8\xd62c\xd4@NN\x92W\x05\xb8\xbe\x7f\xde\xd4PK%KP\x86\x05:\xbb\xa7%<\xad\xb7\xbd齴\x14p\xadHn\xa5\x06\xdc4<\x15!\xf7D\xb3\xf31G\xa6\x9b\xe9\xa2\x1cu\x00\x13ۈ\n\x8f\xfc\x86܃\xb2`\x88>ʊ\xe7V\xd8N\xa0,\xc12y\x10\xec\x1f5lM\x8c\xc4A95\xe0\x05\xa0y\x980\xa0\x04\xe5\xe4Dy\x057H\x92\x82\x9e\x89\x02;\n\xa9D\v\x1e6\xd1\x1b\xf2\xabT@\x98\xd8\xcb7\xe4hL\xa9\u07fczu`&,\x9aL\x16E%\x989\xbfB\xf9g\xbb\xcaH\xa5_\xe5p\x02\xfeJ\xb3Ú\xaa\xec\xc8\fd\x96\x91\xafh\xc9ֈ\xba\xc0\x85\xb3)\xf2\x7f\t\x02\xa0_vp5g+\x8c\xda(&\x0e\xad\x1fP\xea'8`\x17\x80\x93/\xd7\xd5͢!\xb4}e\xa9\xf3\xf9\xfd\xfdC[\xf6\x98\xeeS\x1f\xe9\xde\x12Ȇ\x05\x96`L\xecA9&\xee\x95,\x10&\x88\xdcI\x1f\x8a.g \xfa\xe4\xd7ծ`\xc6\xf2\xfd\xef\x15h+\xe4rCnQ\x93\x90\x1d\x90\xaa̭dn\xc8V\x90[Z\x00\xbf\xa5\x1a\x9e\x9d\x01\x96\xd2zm\t\x9bƂ\xb6\x12\xec7vTk\xfd\x10t\xd9\b\xbf\x9cB\xb8/!\xeb,\x18ۋ\xedY\x86˂\xec\xa5j\xf4\x85SW\x9b\x0e\xc8\xf8\x92\xb5O\xa6ٽ\xa0\xa5>J\xf3\xc0\n\x90\x95\xe9\xb7\xe8!t{\xbf\xedu\b\xc8x\xd4P\xadT\x1ar\xbbΞ(3\x16\xbd\x01Lb\x01\x91/\xa8a\x02<\xd44\x95&\xa6R\x02W\xe9g\xa0\xf9\xf9A\xfe\xa6\x81\xe4\x15\nk\xa6\x00\xa7|Cv\xb0\x97\n\"p\x15\xd8\xfe\xb61(e\t\xa3\x11%Y\x99\ry8\x82%#\xad\xb8\xf1r\xcf4y\xfd\x13)\x98\xa8\fl\x06\xd0F\x18\x8cD\xa1\x86\x16\xf2\x04j\x86^﨡\xbf\xdav=2\xd9\xfe\x04\x01ؙ\xee<\xc9vg\xfbcdV\x9e\xabd\xbboAd\x9a\xacVD*\xb2r&pu\x83\xa0\xadQ5k&ZcD >1\xceø\xcbf\xee\b\xe8x\xa7\x1f\xe4\a\xed\x84t\x8e\x10#\xddZty:\x829\x82\"\xa5\f\xc6'\x82\xf7\x9eq \xfa\xac\r\x14\x9e*A\xe5\a\"\xe2r\xe0܃Ж\xa8\x1e\xe7\xe1\t\x927\x98\xc8\xdb\x1e\xb2\xed\xa1\xbdS\x9e:\r\xef\xfa\xd4\xf1\x8d\xdbF\xb8!\x94<\xc2\xd9y,T\x10\xcb\x1cj\a\x1a\x89t\x86\xc4\xc1\xfd\f\x14\xb2G8#\x18\xbfA1\xdb;U\x14\xdc\xf3\b\xe7\x94f=\x02Z\x9c\x98\xf6\x1b/\x96\x92\xf6\x05\x12\x02\xf3\xd9\xe9\xc4#\xb8\xd9\x14t\xd1\xfc\xe4H\xba\"\tO\xa0\xfd\x05Ӭ\xd9\xd6ڨCƾԎEv\x15\x1cY\x998Qk\xe60\x95 \xf7\xf5v\xd3\x17\xcaY^\x0f\xe4\xe4~+ƽ\xe1\xee\xf3Q\x9a\xad\xb8!\xef\xbf2\xedw\xfc\xdeI\xd0\x1f\xa5\xc17\xcfBN\x87\xf8\x05\xc4t\x1dqy\t\xa7\xb6-\x1d\xda\xfbV\t\xc2\ud7ad\x8b\xf0j\xf60M\xb6\xc2\xc6-\x9e\x1e\xb8\v醛\xb6\x0fݧ\xa84nL\t)\xd6.\xf5\x12\x1b\xc9\x11;\x11\xa4T\x1d\x8e\fQ\xab\a\x1d\xc9\xf5ğ\akI\\\x7f\xb7\xaf\xcai\x06y\xd8W\xc1\xdd@j\xe0\xc02R\x80:L\x19\x8e\xf6SZ\xfd\x9e\x86B\xa2\xd6u\xcfB\tK3\xed\xe1\xf1\xaa;\x9a\xfc\xee>k\xbbr\x13Z\x05f\xcf6\x1d\xd9\x04\x1co:?#4\xb1\xe8\x7f\xccR\x97\xe69\x96iP~\xb7@\xe3/\xe0\xc5\xd0\xf6;Ĝ\x85,(nN\xfc\xb75s(\xd0\xffCJ\xcaT\xc2\x1a~\x8b\xe5\x18\x1c:}}\x16\xab=\x8c\x1d\x81ib\xf9{\xa2|\xb8\xbd\x1c\x99\x9c\xb4\xba\x05\xb83\xe4r?\xf0Xn\xc8\xd3QjgSqSd\x16$\xd3d\xf5\bg\xbf\x19\xd7\xd6\x03\xab\xadX9\x03\xbfX\xdd\xd4ނ\x14\xfcLV\xd8w\xf5-NP\xa2$&6\xfb\xba~\xac\xcbO\xd6\x05-\xd7^z\x8d,X6\xda\x0f\xcbeR]l\x1b\x83\x06\x0f\xc2v\xackD\xac{<5\xdb$\xf9-\xa5\x8e\xec|\x8f\xa0r'\xb5q\x19Ɏ;\xbb$\xfbE\x9c\xec\xf9\xac\x17\xa1{W\xa5#U\xa8\xbf\xb0겗\xa8\xb5\xdc\xd6Ӛ\xd9\xed\x19\xf8L\x9a\x03j\x03\xb2U\xb3\xf2\x9d\x1e^\xb9=\v\x1c\x84f\xe8\x94\xcc\xc2-\x95\xcc@Gw\x8b\x9b'A\xcb\xcf$\x17\xeb\xc4\"u\x81\x8f+n\x98Nf\x86'ݑ\xb5DZ\x18\x02\xbc\xff\xda\xcazZ\xa5a\xff\x9e\x13\xbe\xa5x\x11\\\xebEA\xfbU\v\xd9f\xc6J\xc6bO\x87m\xa1v\xac]\xd4VЯ\xac\xa8\nB\vK\xfa\xd4pi\xef*\xce:\x1c\xaf\xeb\xce\x10.\x9a\x11#\xed\xa2*9\x98\xd4\x15\xe9*\xcc\xec2\xd1,\x87\xda0{)\x90\x82P\xb2\xa7\x8c\x8f\x94\xbb\f\x9fE\xb4]\x12\xa3xeq\xbd\xe0#m\xf05\x92\"!\x81\x9b\xe8dNk\xebR\xa5\xbb\x8aw\n\xd2ܳ\xb9dvp\xcfJ\xc5$\xd6\xe9]\xd9C\xf3\"F\xc5\xf9\x87\x8b6x~\xb8h3\xcf\x0f\x17m\xf4\xf9\xe1\xa2\xcd??\\4\xff\xfcp\xd1\xc2\xf3\xc3E\xfb\xe1\xa2M5\x9b\xd2\xd6s\x18\xb9\xd3q#?\xceb\x91\xb0\xad=\x85\xe2\x04|_\x85\xe1\xeb\xbcS+3\xb7\xf1^\x91:\xfe\xe4\xdap\xdd2%u\xa9\xa6] A\xbc\xdda\x9f\x99\xe2\xcdo\xa8\x97\x0f\x83^T/\xbf\x9d\xec|\xa5zy\x8fa\xdf\xeb\xbeR\xb5|\x98\xff\xb2j\xf9\x1b_\xaaQ\x00\r\xe9y\xb7\x17\x9f\x8f\r\xd9\x1bm\x00\xf8\x0f\xae\xbf\x1dԇ]\xc6\xf8g\xaf\xb6\x1fa~ba\xfc\xea/\xab\xef\x8fҋi;J\xcd\x01\x99\"\x93\n\xc7|m\\\xd9.\xee\xea\x16\xd2}\x9f¹T\x1aS+\xe6\xa7\xe85\xd42-\x82}\xaf\x8b\xd9@\xf1\xa9\xf4\xb6\"\xedD\xe76\xd2e\xeeLgd>\x98\x04\xd0g\x91\x1d\x95\x14\xb2\xd2>o`\xa1\xbf\xc5\xf4\x85\xdf\n\xc52\xb0D\x05\xfb\x9a\x1ce\x15\xa9؞\xa0\xddL\xfd\xdex՞ߣ\x06CO\xaf7\xdd_\x8c\xf45|䉙c\x04ϧ#\b\xdc]\x17\x87vA~Xp\xfe\xc0y_\x90\x88TD0>f\xb0\xeaS\xf9\x1d\xd3\xf4\xa9tI\xa2Ŗ\x7f:\xc1\x91V\xe5wqm_\xb7vo\xc4\t\\\xba\x99\x9d~\x84!\xbdzo\xba\xdcnI\xcd^\xbf\"o\x14\xe8|\xa5^Jnj\xa6*\xef\x82Z\xbc\xc4:\xeco\xdezO\xa9\xb6\xbb\xa8\xc6n\xb6T9\xb1\xb2\xae[37\rrA=]\x12q\xe6k\xe7\x16W\xcc\xf9\n\xb5\xc9y$\xd7\xc9E*\xe0&\x01\x8fV\xc7Mս\xcd佇5q\xe9\xd5n\x93\xa0\xb1\x12n\xbe\xc6\xedz\x95\xec\u05c8\xb2\xc7U\xcdl\x9d\xdal\x14>\x8d\xdfl%ڒ\xfa\xb3Y\x8a]XkVג\x8d\x8c\xbb\xb4¬[A6\x024\xa5\xael\xa4nl\x04\xe2d5Yj\xb5\xd8\b\xec\x19\xb3;)%\x93?.\xa9\x12\x8b_\xa2Bf\xad!\xff\xa3\xe4\xefR2H\xd5q.\xe7\x02\x9aO\xbd\xe6\x96\xf3\xc1ǚvVc~*3\xc7\xe5\xcejQq\xc3J\x8eۋ'\x96Gcvs\x84s}1\xc4\xef\x12\x8fk\xba\xcbLȧϵ0oz.7\xd5\xe4\t8'4&\x8a\x83\x99g\xee\x1e\xa0L\xae\xc1Z\b\xbb<\xfd\x95\x17\xfe\xba\xa0\x1b'\xefx\"5\xb6\x03c\x8ePX(\xe3מ\x8c\xaa\xf2iw\xd2y\xbe\xf8\xee\xef\x15\xa83\xc1\xebYj\xffb\xe6<\x94[\x96\xda\xc6BAQxm\xe3n\x9f\xea\xb9\xd9\xcd\xf2$o\x853xQ\xb0=\x1c\x11\x8e\xd5\x10\xbc\xe6\xb5U\x866j\x18i\x1aO\xc4ʺw\xe4\xf79O5\xf50\xd1\xf3\x06\x1a\xcbC\x8dY#\xff,\xe1\xc6\xe5\x01\xc7\x04\xc8\xd4\xc3Ai\x1bⳇ\x81\x9e+\xf0\x98\v=\x92}\xae\xb4\xc3>\xcfq\xc8g\xc1\xe1\x9e\x05!Ȳ $\x99L)\x87x\x9e%\x14y\xc6`\xe49\u0091\xcb\x02\x92\x19\x90\xbd\xc39)\xc7n\x92\x8a=\x92\xf7;S\x8a5\xe6\xb7$\xa7\x8f\xd3$\x1c\xa3Iج\x9c\xc34\xe1\xb8̲c2\t4|\xa6P噂\x95\xe7\bW\x9e7`\x99\rYf%g\xe6\xe7e\xc7[.N\xdeK\x95\x83\x9a\xdc\xebH\x15\xcdI\xa1\xec\xc5\x17\xdd1{\x99\xffp\xa7\x9cm\xd5qec\t\xeb\xfa\xd4{F~f\xc2\xef\xa3Z!l\xd9\xfd\xce\x06L\xe3\x88\xc4\xf3\xff\x8d\x97\xe7o\x1bu\xbb6\x1aJ\xaap\x87uwv\xa5\x15zC\xde\xd3\xec\u0603~\x8c\xc6\x15{\xa9\njȪ\xde\xf2z\xe5\x80ۿW\x1bB>\xc8zӾ}\x93\x8cfE\xc9\xcf6n\x88\xc0\\\xb5A\\&\x10Q\xe1\v\xe3\xdfIβ\x88\xa7\x15\xbd\\\xc85\x1e\\\t\x81W\x1ee\xed\xad\xef\xd26\x8c;Z\xe8\x94u\xafW\xdcK\xce\xe5\xd3\xc2p\x9c\x96\xec?\xf0\x96\xe6\xf9\x1c\xceۻ-6\r\x92\x82\xb7;\xd7\x15B5\xd2;\xb0\x16\xb3\x99\xce؊\xdf\xee;\x10#\x95v\xf5\x9f(\xad\xb5\xc5fc\xb7.\xb9\xaa?\xabi\xee\xb6\x0e\xbb\r\n\v\x15g\"\xb1\xd6\xc3\x1c\x99\xca\xd7%U\xe6\xec\xea\nnj\x1c\xc6\xf38\xc1nNe[F\xcd\xcb\xf0\xba\xdf(mí\xbf\xb8\x99w.\xbb[\xa1}\x8a^\x82\xc7\xf8Q\xbe\xd9C|W\xc4c\xdc\x05Y#\xa5\"\xaf\xa3EIW\xcbbi\x7f\xb5\xed\xaf\xf2\x04\xef\xa2٬\x0ey\xee{\xcd#\xe5D\x01\xa2\xbb\xdcu\xeavP\xbc\x9c\xf32]\x14\xaf\x0f\nC\xfb\xeb;\x13\xe7\xe2[G\xa6\x12n.\rpu\x01\xfe\x95wݭ\x1b\xc39\xf0\x0f\x8c\x83vh%(ѻa\xafZ\xa7V\xc5\xce9j{\xfbc=\xc0\x88\xf5q\xd3\u009co\t\xca:F.;\\\xe9 \x96\xe3\x13o8\u0084\x81C$\xdf<\xa1EO\x9d\x8b\xbf\x83Hϩ\x94/\xf1^\xad|`kQ9W1\xaaQ\xc6ാ}\x80\x99r<^~\xdd[2ǜ\xff\xb1\xdb\xe1\xf1F\xf4\xf9\xfb\xe1\xdd\xc5\xe9\xfek\x10^\x90+\x85W\\\xfaK\xd5\xf1Jȋ\xae\x88\xdf\xd5uP\xc6/\xa2\x83\xeb8B\x047\xb7Q\xbb\x97\xc4f_\x84\v\"\x0f\x8bw`\xba탧D\x96\xd1\xc1\xb3\xc0\xd7\xc6iC\x8b\xb9\x9b\xeeo\x87=\xf03$*oU\xd3\xd5\u05f5?Qݰ9\xa6f\x1bp\xae'\x86\f\x16\x1a\xe4\x04N \x88\xb5S\x8e\xbe\xe1S9\xfd>\x11\xa8m(\xfe\x18\x85\xd3\xf5A\xf3\x87\xc8\xdf\x7f^\xe5\x01\xdd-u\x02\xf5RO\xc0\xac/\xe0\x8f\x10a(\x99.\x14\x7fc}YXG\x81&\xb9jQ]\x9bi\xd6\xd5\xf3\xc9J\xeb\xf6~;\xd6sT\x82C\x83\x18\xff\x06\x1f\xba\xf8F%5\x9cY\xaa\x8a\x1a\xcelNAu\xd4Qdr\x8d\x82\xba\xfa4q\xad\xceސ\x8d\x8d\x9c\a\x80\xc7\xc1\xc2\xe7\x0f\xdcy\xb0\x02\xb4\xa6\x87p5\xf6\x93u\x98\x0f \x00\x93G\x91\xd9\xf8t|s~\xa8{1\xb4\xdb7\xa4\x99\xa9\xa8\x1f Tg\xb6Z\xbd\x8c)`.\x0f\xee\xc3\x15,|\xb0(D\x12\vi\xf2\xb5d*%\xf2x_7\xb4\xb4A\xa7\x0e\x19\xd1|`\n8;0\xeb\xb6[&\x1d\xa8\xda\xd1\x03\xac3\xc99\xa0\xae\x1d\xe2\xf5\x9c\x8b՟\xd2\xfa\fT\xcfN\xedC\xbb\xad\xdf_r\xdcv\xf7*RW\xa8\x8c\xdf\x1b2LA\xf3\x01\xaf\x01B\x12\a^\x14i8*D?u5Ĵ\xdd6,0\xafW}\x16\xd2\x7f\xf9\xea\xc6Ǯ\xf1\xe4JA\x7f\x97\xea\x86\x14L\xd8\x7f\xa8\xc8\xdd\x06P\xe8\xbc\b\x7f\xbc\xf1|\x06\xef;ۦ>,\xdb\xf2#!,\x88\xb1\xc8:~@rM>\xc20\x10tg\x1e!\xc7-\xcf\xd8\xf7\xbdl\x93\xad\xb8S\xf2\xa0@\x0fW՚\xfc\x8d2\xc3\xc4\xe1\x83Tw\xbc:0\xd1\xf8\x1b\x8b\x1a\xdfQe\x18\xe5\xfc\xec\xf0\x89!\xca\x04\xe5\xec\x1f1\xee\xb4\x7f\x9c\aT\xab\xdb\xc8o\th\x8c\xfd\xf0\x0e\xac\xa9\x1d\r7\xe2\x82\xe0\xe9:'\v\xbeY\xb3EÄ\x93]<_\xb9\x93\x95\xe9(\xbfFy\xc6\xe2]\x0flC>J\x03a\xe7\x9fuaZs\x01ڬa\xbf\x97ʸ\x1d\xa1\xf5\x9a\xb0\xbd\x0f_b)}\xca8F\xb1\xee\x03a\x84\x99\xa6ԳYo\x98IR\xa86\xf0Fゞ]\xbe\x97f\x99\r\xf8\xe1\x956\x94G4\xf27\xc5\xf8\x18'\xda\xf5\x02\xf9o)i\xf0m\xbb\xfd0\xaeGp\x8erx\x16\xdaY\xa3\xa8m&\x98\a\x04A\x9e\x143\xc6Z\x80vi\x171V\xe7sN\xb4Ղ\x17\x05\xf8\xc4y\v\xdb\xf1\xad\xe6n\x02\xa9n<\xe6l\xf8\xc9\xe1\xf7\xb0vH\x82\xd1ą\xdfR\xf7}-+\xb3#\x15\a+TJV\x87c\x90\xcb\x11[>\x027\xaf\x00\x93!\xa8!t(\xab1\x95\x12\xad\xad\xb7\xfa|_\x83.\xcd\x1eG1\xf5\xa5\x03\xe1#\x95\xaf\xfcE\xf7뽒\xc5\xda\xf3\x02\xaban\xfcv\x98b\xd2\x06\xec\xe6\x18%9q\xdf\xc0\xf27J\xa3\x18\x94%\bB\xb5\xc7'\xe1\"\x90\x8b\xf36\xdaPeR\xe3\xa0\xfbN\xe3\x99\x10\b!\xc7\xf1\xbd\xf7\xdb}\xeeB\x94[\xff\t\xb8\x1a\xf0\r\xd1L\x84\xefc\xba\xcdD'\n\xdaFF\n0\x19\x1a-t\x1a\xc44\x9d\b\xa6\x8b\xfe\x1f\x1b\xbc\x9cj\x9b\xf8>\xc5\v\xfe\xd2k\xde;\xf4\x86\x1fC\xab\x9bx\xcf5B\x8f?\xb1\xbd\xab\xbd\xca,\xd6\x7f\xfe??\xccvJ\xf2\xb2^N:X\xe8;՞\xd2̧\xcf\xee8X\xcfG\x03t}\xb7\x97\x8b\x9c\xf4\xd3ea\xe75c\xce\xf0\xe9\xd6\xebDb\xa7ˢ\xcdg\v5\xaf;\xbb'\x8a\x9f\x8b\x9c[c\x7f\xf3\xcd\"\xb1\xa6\x87\x10\x896#Ө\xe3\xcf\xd9h\xb3\x15l\x06\x1cG\xbe\xee\xd4\v@\xaf\x14nF\xed\xc0\xe0%*м\xb5\xb6\xfdH\xfe\xcd\xff\x06\x00\x00\xff\xffw\xe0\xabZYz\x00\x00"), []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xc4YKs\xe3\xb8\x11\xbe\xebWt\xed\x1e|YQ3\x9bKJ\x97\x94FN\xaa\xa6\xe2\x89]#ǹ\xe4\xb0\x10Д\xb0\x06\x01\x06\x0fi\x94T\xfe{\xaa\x01\xf0!\x92\xb2\xe4\xa9$\x8b\x8bM\xb2\xd1\xe8\xfe\xfa\r\xcd\xe7\xf3\x19\xab\xe5\vZ'\x8d^\x02\xab%~\xf3\xa8\xe9\xc9\x15\xaf\xbfw\x854\x8b\xc3\xc7٫\xd4b\t\xeb༩\xbe\xa23\xc1r\xbc\xc7Rj\xe9\xa5ѳ\n=\x13̳\xe5\f\x80im<\xa3\u05ce\x1e\x01\xb8\xd1\xde\x1a\xa5\xd0\xcew\xa8\x8bװ\xc5m\x90J\xa0\x8d̛\xa3\x0f\x1f\x8a\x8f?\x17\x1ff\x00\x9aU\xb8\x84-㯡v\xdeX\xb6CexbY\x1cP\xa15\x8543W#\xa7\x13vքz\t݇\xc4!\x9f\x9e$\xff\x14\x99m\x12\xb3\x87\xcc,~W\xd2\xf9?_\xa6y\x90\xceG\xbaZ\x05\xcb\xd4%\xb1\"\x89\xdb\x1b\xeb\xff\xd2\x1d=\x87\xadS\xe9\x8bԻ\xa0\x98\xbd\xb0}\x06ษq\tqw\xcd8\x8a\x19@\x86&r\x9b\x03\x13\"\x82\xcdԓ\x95ڣ]\x1b\x15*ݞ%\xd0q+k\x1f\xc1L\xba@V\x06\x1am\xc0y\xe6\x83\x03\x17\xf8\x1e\x98\x83ՁIŶ\n\x17\x7fլ\xf9?\xf2\x03\xf8\xd5\x19\xfd\xc4\xfc~\tE\xdaU\xd4{暯\xc9FO\xbd7\xfeD\n8o\xa5\xdeM\x89\xf4\xc0\x9c\x7faJ\x8a(ɳ\xac\x10\xa4\x03\xbfGP\xccy\xf0\xf4\x82\x9e\x12B@\x10!4\b\xc1\x91\xb9|\x0e\xc0!q\x89\x18MK\xaaFg\x9d\x89M\xa2\xc0ˀK\x92\x9f\xded\xe9{l\x1b\xff.\xb8Ŗ\xa5\xf3\xac\xaa\xcf\xf8\xaevx\x89\xd9\x19\x14\xf7X\xb2\xa0|_U\xb2\x92\xea\xfb\xe5\xb9Z5\xf2B\xa4]g'ޟ\xbdK\xa7n\x8dQ\xc8\x12\x97Du\xf8\x98\xbc\x90\xef\xb1b\xcbLljԫ\xa7\xcf/\xbfۜ\xbd\x86)G\x1a\x04\x05\x19\x8e\xf5l\xb3G\x8b\xf0\x12\xe3/\xd9\xcde\xd5Z\x9e\x00f\xfb+r\xdf\x19\xb1\xb6\xa6F\xebe\x13,i\xf5rQ\xef\xed@\xa6;\x12;Q\x81\xa0$\x84ɏr\xbc\xa0Ț\x82)\xc1\xef\xa5\x03\x8b\xb5E\x87\xda\xf7\xe1m\x05+\x81\xe9,^\x01\x1b\xb4Ćb9(A\xb9\xeb\x80փEnvZ\xfe\xb3\xe5\xed\xc0\x9b\xec\xbc\x1e\x9d\x1f\xf0\x8c\xf1\xa9\x99\"W\r\xf8\x130-\xa0b'\xb0H\xa7@\xd0=~\x91\xc4\x15\xf0\x85\xfc]\xea\xd2,a\xef}햋\xc5N\xfa&\asSUAK\x7fZ\xc4t*\xb7\xc1\x1b\xeb\x16\x02\x0f\xa8\x16N\xee\xe6\xcc\xf2\xbd\xf4\xc8}\xb0\xb8`\xb5\x9cG\xd1uJ\x9a\x95\xf8\xd1\xe6\xac\xed\xee\xced\x1dEmZ1k\xbea\x01ʘ\xc9\v\xd2֤E\a4\xbd\"t\xbe\xfeq\xf3\f\xcd\xd1\xd1\x18C\xf4#\xee\xddFי\x80\x00\x93\xbaD\x9b\x8cXZSE\x9e\xa8Em\xa4\xf6\xf1\x81+\x89z\b\xbf\v\xdbJz\xb2\xfb?\x02:O\xb6*`\x1d\v\x13l\x11B\x1d㾀\xcf\x1a֬B\xb5f\x0e\xff\xe7\x06 \xa4ݜ\x80\xbd\xcd\x04\xfd\x9a:$N\xa8\xf5>4\xb5\xf0\x82\xbd&\xa3xS#?\x8b\x1f\x81NZ\xf2p\xcf<Ƹ\x18\xe0\x9aC\xfcr1m\xd6tp\xd3b\x9c\xa3s_\x8c\xc0ᗁȫ\x96\xf0L\xc6\x1am%],\x8bP\x1a;\xac\x18\xac\xcd\xc0\xfd\xd5d\xaab\xf4\ru\xa8Ƃ\xcc\xe1+2\xf1\xa8\xd5\xe9§\xbfY\xe9\xc7\a]0$\xad$\xe2\xe6\xa4\xf9\x13Zi\xc4\x15\xe5?\r\xc8[\b\xf6\xe6\betk\xedՉr\x90;i>ζ\xcdZ=}n2o\n\xa0\x1co\x19\xab\x02V9rM\t\x1f@HG\r\x80\x8bL\xc7`\xe9\xa0b\x83\xb0\x04oû\xd4\xe7F\x97r7V\xba\xdf\xd3\\\xf2\x98+\xac\aȭ\xe3I\x94\x9a\xc8;jk\x0eR\xa0\x9dS|\xc8R\xf2,I\xb0\xa9r\x95\x12\x95pcM/DYTŢ\xa0\xa8f\xea\x8a\r\xd7-a쀙\xd4Ƀ;\x061\xd9\xd8*\x97T\xedQ\x8b\xb6\x1b9\x93\xc6Ĭ\xe5P\xc0Q\xfa}J\x87j*\xee\xe0\xcdأ\xf5\x8a\xa7\xa9\xd7\x03ٟ\xf7H\x94\xa9\x80\"8\xe4\x16}\xf46T\xe4>\xe4J\x05\xc0\x97\xe0bB\x1d\xe6\x89f\xc5F\xad\xd9\xfd\x8a\xa71\xd0p\u0378\xb9\x85\xb9.\xf2\x1d\xb5\u038d\xc0\x16K\xb4\xa8\xfddR\xa7\x01\xc4j\xf4\x18\xf3\xba0\xdcQJ\xe7X{\xb70\a\xb4\a\x89\xc7\xc5\xd1\xd8W\xa9ws\x02|\x9e#h\x11NJŏ\xf1\xcf\x05\x95\x9f\x1f\xef\x1f\x97\xb0\x12\x02\x8cߣ%\xab\x95A5\x8e\xd6\xebo~\x8a5\xf6'\bR\xfc\xe1\xee{p1u\x8a\x9c\x1b\xb0\xd9D\xef?Q\xa3\x16\x85\"\x886\xc9*\xc6\x02UJ2v\x95\xad\x99r͔#Nu\x98\xfdE\x89\x89*\xc8TF}\xc5q2}#\xcc\x00\xbe\xcd;C\xcd+V\xcf\x135\xf3\xa6\x92|6\xd46\xb6\xc1W\"\xb2i\xbb\xa5\x16\x92S\xdbv\x1eI\xcd8\"κ\xf3\t\x18\x86\xfd\xfa\xa5\xfc1\rSR7W\xcf+\x12?\xf6i\xbb!.%\xb3\\\x11\x1dzj\xb7\x1ch\xa4\x8a\xc9\xec\x18\xe7\x98B\xb8њb\xd7\x1b`mb\xbcsÊ\xf0\xce|\xb2\r\xfc\x15'\x80\x1f\xa9\xf2)\x126\x18\xa7m$Kp\x18S\xf551\xe0zDp\xb6F{\x8b,\xeb\x15\x11\xb6E\x95\xc1z\x05۠\x85\xc2F\xa2\xe3\x1e5\xcd\x13\xb2\x14?\xfcf3\x93b\xce\xd3\b\x84\xe2+\x1e\xe4\xf8Nh\x8c\xee\xc3hG\x13\xf8m8\xd0\xc3/\xcdh\xbd\xb0\x99\xec\x97\t0J\xa9\xa8s\x9c\xc8\x13]\xc70\xbe\xbd\xfc\xb4y\xb8s\xb1\xe1G\xed\xa7\x9a\xc4#Z\x8c\xf3\x15\n\xea\xf9M\xbe\xc5\bΣ\x9dp\x80\xd6z\xd1栌\xde\r\x02'\xad|\xa7A\xfd\\r(cA\xa0\xa7Ҥw\xc0\xf7Lﰻ\xb3\xca\xf2\xbf-)\xb9\xcf\xc0g:\x0f\x91\xfa\x92{\xdcd\xd1g9\xd5ԏ\xee\x8b;\xe2\xe9\xbb\xe2F\xfaƲ\x17\x87\xa2+\xb8\x8f\xe8\x9b*M\xa0\xce}w\x7fܭ\xef\x1f\x86Ǘ\xd37 \xf1ޛ\xf37nA\xe0\xc8\\w\x87\xfe\xdb\xe1PQ\xb7z\xb5\x05\xfe\x92\xa8\xd2ec\xde\x02lk\x82\x7f+2\xef\xa6\x1c:\xff8\xf0\x1e\x19\xe3O\x1eך\f\xa2i,\u0083\xa5\xc1\xb3\xbbC\x8bIa\xaa\xb6\xdc~\x19\xb5\x1a\xfc2\xd3\xff6\xfe\xdd\xe6\x06\xbd&k\xed\xe8e\xaa\x97=\xbbf\x90\xfbo¶\xbdW^¿\xfe=\xfbO\x00\x00\x00\xff\xff\x80.\x12\xd3P\x1c\x00\x00"), []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xb4\x96M\x93\xdb6\x0f\xc7\xef\xfe\x14\x98y\x0e\xb9<\x92\xb3\xed\xa5\xa3[\xb3\xc9a\xa7mƳ\x9bɝ&a\x8bY\x8ad\x01\xd0[\xb7\xd3\xef\xde!)\xf9E\xb67\xdbCy\x13\t\x02\x7f\xfe@\x80j\x9af\xa1\xa2\xfd\x8a\xc46\xf8\x0eT\xb4\xf8\x87\xa0\xcf_\xdc>\xffĭ\r\xcb\xdd\xdd\xe2\xd9z\xd3\xc1}b\t\xc3#rH\xa4\xf1#n\xac\xb7b\x83_\f(\xca(Q\xdd\x02@y\x1fD\xe5iΟ\x00:x\xa1\xe0\x1cR\xb3E\xdf>\xa75\xae\x93u\x06\xa98\x9fB\xef\u07b7w?\xb4\xef\x17\x00^\r\u0601A\x87\x82k\xa5\x9fS$\xfc=!\v\xb7;tH\xa1\xb5a\xc1\x11u\xf6\xbf\xa5\x90b\aDž\xba\x7f\x8c]u\x7f,\xae>\x14W\x8f\xd5UYu\x96\xe5\x97[\x16\xbf\xda\xd1*\xbaD\xca]\x17T\f\xd8\xfamr\x8a\xae\x9a,\x00X\x87\x88\x1d|β\xa2\xd2h\x16\x00㱋\xcc\x06\x941\x05\xa4r+\xb2^\x90\xee\x83K\xc3\x04\xb0\x01\x83\xac\xc9F)\xa0\xbe\xf4X\x8e\ba\x03\xd2#\xd4p \x01\xd68*0e\x1f\xc07\x0e~\xa5\xa4\xef\xa0ͼ\xdaj\x9a\x85\x8c\x06\x15\xf5\x87\xf9\xb4\xec\xb3`\x16\xb2~{K\x02\x8b\x92ē\x88\x12\xd7\x06\x0ft\xc2\xf7\\@\xb1oc\xaf\xf8<\xfaSY\xb8\x15\xb9\xda\xec\xee*i\xdd㠺\xd16D\xf4?\xaf\x1e\xbe\xfe\xf8t6\r\xe7Z\xaf\xa4\x16,\x83\x9a\x94fp\x95\x1a\x04\x8f\x10\b\x86@\x13Un\x0fN#\x85\x88$v\xbaZu\x9c\x14\xcf\xc9\xecL»\xac\xb2Z\x81\xc9U\x83\\\xa0\x8d\x97\x00\xcdx\xb0\n\xd32\x10FBF_\xeb\xe8\xcc1d#\xe5!\xac\xbf\xa1\x96\x16\x9e\x90\xb2\x1b\xe0>$gr\xb1\xed\x90\x04\bu\xd8z\xfb\xe7\xc17\xe7s\xe6\xa0N\xc91?\xd3(\x97\xce+\a;\xe5\x12\xfe\x1f\x9470\xa8=\x10\xe6(\x90\xfc\x89\xbfb\xc2-\xfc\x961Y\xbf\t\x1d\xf4\"\x91\xbb\xe5rkej\x1a:\fC\xf2V\xf6\xcbR\xffv\x9d$\x10/\r\xee\xd0-\xd9n\x1bE\xba\xb7\x82Z\x12\xe1RE\xdb\x14\xe9\xbe4\x8ev0\xff\xa3\xb1\xcd\xf0\xbb3\xad\x17\x17\xa4\x8eR\xe8\xafd \x97yM{\xddZOq\x04\x9d\xa72\x9d\xc7OO_`\n]\x921\xa7_\xb8\x1f7\xf21\x05\x19\x98\xf5\x1b\xa4\x9a\xc4\r\x85\xa1\xf8Dob\xb0^ʇv\x16\xfd\x1c?\xa7\xf5`\x85\xa7+\x99s\xd5\xc2}餹\xa8S4Jд\xf0\xe0\xe1^\r\xe8\xee\x15\xe3\x7f\x9e\x80L\x9a\x9b\f\xf6m)8}\x04\xe6ƕ\xda\xc9\xc2Ծo\xe4\xebJ\xd1>E\xd49\x83\x19b\xdem7V\x97\xf2\x80M x\xe9\xad\ue9e2\x9d\xd1=\x14x{\xb6p\xbd\xa0\xf38\xb6\xc9\xf9\xca\xcd\xc3Cɝ%\x9c\xdd\xc2\x06.z\xee\xeb\\J3\xfc\x97dj'\x1e\xd9\xe8D\x84^N\xfa\xb3\xba\xb6\xe9\xad,\x90(\xd0\xc5\xecLԧbT^ze=\x83\xf2\xfbq#H\xaf\x04^\x90r\x19\xe8\x90r\x9fA\x03&]\xf0\x1b\xb1\x9c\xbe%\x91\x82F\xe6\xf6\xc2\xce\n\x0eW4\xbd\x92\x9d<|rN\xad\x1dv \x94\xf0Ff\x15\x91\xda\xcf\xd6ʛ\xf5\x1d\x04\xabls-\a\x87w\xfa\xbbI(\xb8}\x1a.#5\xf0\x19_\xae\xcc>\xf8\x15\x85-!ϯ|^\\Uz\x87\x9f\x817P\xbaz)/&9\xf7;sB\x91%\x90ڞr\xe5\xb4>\xf4\xef\x0e\xfe\xfa{\xf1O\x00\x00\x00\xff\xff\x045\f\xc6i\n\x00\x00"), []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xb4VM\x93\xdb6\f\xbd\xfbW`\xa6\x87\xb43\x91\x9c\xb4\x97\x8eo\xad\x93\xc3N\xd24\xb3N\xf7NS\xb0\xc4.E\xb2\x04\xe8\xcd\xf6\xd7w@J\xfe\x94\xbd\xdeCu\x13\t\x82\x8f\x0f\x0f\x8f\xac\xaaj\xa6\x82y\xc0Hƻ\x05\xa8`\xf0;\xa3\x93?\xaa\x1f\x7f\xa5\xda\xf8\xf9\xf6\xfd\xecѸf\x01\xcbD\xec\xfb{$\x9f\xa2\xc6\x0f\xb81ΰ\xf1n\xd6#\xabF\xb1Z\xcc\x00\x94s\x9e\x95\f\x93\xfc\x02h\xef8zk1V-\xba\xfa1\xadq\x9d\x8cm0\xe6\xe4\xe3\xd6\xdbw\xf5\xfb\x9f\xebw3\x00\xa7z\\@㟜\xf5\xaa\x89\xf8OBb\xaa\xb7h1\xfa\xda\xf8\x19\x05Ԓ\xbb\x8d>\x85\x05\xec'\xca\xdaa߂\xf9Ð澤\xc93\xd6\x10\x7f\x9a\x9a\xfdl\x86\x88`ST\xf6\x1cD\x9e$\xe3\xdadU<\x9b\x9e\x01\x90\xf6\x01\x17\xf0E`\x04\xa5\xb1\x99\x01\fG̰\xaa\xe1t\xdb\xf7%\x95\xee\xb0W\x05/\x80\x0f\xe8~\xfbz\xf7\xf0\xcb\xeah\x18\xa0A\xd2\xd1\x04\xceD\x9d`\x06C\xa0`@\x00\xecw\xa0@9P\x91\xcdFi\x86M\xf4=\xac\x95~La\x97\x15\xc0\xaf\xffF\xcd@\xec\xa3j\xf1-P\xd2\x1d(\xc9WB\xc1\xfa\x166\xc6b\xbd[\x14\xa2\x0f\x18ٌ,\x97\xef@C\a\xa3'\xc0\xdf\xc8\xd9J\x144\"\x1e$\xe0\x0eG~\xb0\x19\xe8\x00\xbf\x01\xee\fA\xc4\x10\x91\xd0\x159\x1d%\x06\tRn8A\r+\x8c\x92\x06\xa8\xf3\xc96\xa2\xb9-F\x86\x88ڷ\xce\xfc\xbb\xcbM\u0090lj\x15\x8fr\xd8\x7f\xc61F\xa7,l\x95M\xf8\x16\x94k\xa0W\xcf\x101\xf3\x94\xdcA\xbe\x1cB5\xfc\xe1#\x82q\x1b\xbf\x80\x8e9\xd0b>o\r\x8f\xbd\xa3}\xdf'g\xf8y\x9e\xdb\xc0\xac\x13\xfbH\xf3\x06\xb7h\xe7d\xdaJE\xdd\x19F\xcd)\xe2\\\x05Se\xe8.\xf7O\xdd7?ġ\xdb\xe8\xcd\x11V~\x16\x99\x11G\xe3ڃ\x89\xac\xf9+\x15\x10\xd5\x17\xc1\x94\xa5\xe5\x14{\xa2eHع\xff\xb8\xfa\x06\xe3ֹ\x18\xa7\xec\x17\xe5\xec\x16Ҿ\x04B\x98q\x1b\x8c\xa5\x88Yy\x92\x13]\x13\xbcq\x9c\x7f\xb45\xe8N駴\xee\r\xd3(f\xa9U\r\xcbl(\xb0FH\xa1Q\x8cM\rw\x0e\x96\xaaG\xbbT\x84\xff{\x01\x84i\xaa\x84\xd8\xdbJp腧\xc1\x85\xb5\x83\x89\xd1\xc9.\xd4\xeb\xa4\xd5W\x01\xb5TO\b\x94\x95fctn\r\xd8\xf8\bj\xdf\xf9\x03\x81\xf5Q\xe6\xe9\xce\xcd\xe0Tl\x91OGO\xb0|\xcbA\xb2\xfdS\xa7\x8e\x8d\xe6G\xac\xdbZ\xbc\x82\x06 \xc5=~\xaa\xcf2^\xc6\x00\x93\xea\x9dD2\x8aXh\x10^\xc5\nĤ\x0e1\x9do-\x1f\xba\xd4OoP\xc1\xef\x19\xf3g\xdf^\x9d_z\xc7\"\xf7\xabA\x0fަ\x1eWN\x05\xea\xfc\v\xb1w\x8c\xfd\x9f\x01c\xb91\xaf\x86\x8e\x17\xef\ue5ba\x12\x98\xec\xc5}\xefQ\xfc\x1e/\x9ft\b\xb8)\xcb\r\x98\x86ț\x0e\xba\\ݽ\x86\xc2\v\xe1\xaf(ҝ\xdb\xf8\xe9\xb8\v\xed=~\xf9\x1a\x7fY\xab\xf2\x10\x18\xb5*K\xca݆\xf0)\xad1:d\xa4\xbd\xcd>\x19\xee&3\x02}S\xe6\x84H\xf9\x01\xa4\xd5\xe9\xd3K\xbe5B\x83\x16\x19\x1bX?\x97\x1b\xe9\x99\x18\xfbs\xdc\x1b\x1f{\xc5\v\x90˻b3!#\x97\xacUk\x8b\v\xe0\x98.\xa9l\xf2\xe0\xa1S4цGg\xfe*1S\xc2\xd85\xe3Ue\xc0\xc5{\xa3\x82/\xf841\xfa5z\x8dDx\xdeF\x17O2\xd9\x04g\x83$/\xac急\xe1\xe1>\x8c\xfc\x17\x00\x00\xff\xff\t\x15i;\xcd\r\x00\x00"), - []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xc4YKs\x1c\xb7\x11\xbe\xf3Wt\xc9\a\xc6U\x9aY[I\xa5R{\x93\xa88\xc5ĦX\xa2\xa4\x8b\xcb\a\xec\xa0g\x06\xe6\f\x80\x00\x98%7.\xff\xf7T\xe3\xb1;\x0f\xec.Ɋ\x1c\\\xc8ţ\xf1\xa1\xdf\xddS\x14\xc5\x05\xd3\xe2\v\x1a+\x94\\\x03\xd3\x02\x1f\x1dJ\xfae\xcb\xfb\xbf\xd9R\xa8\xd5\xf6\xfb\x8b{!\xf9\x1a\xae\x06\xebT\xff\x11\xad\x1aL\x85\xef\xb1\x16R8\xa1\xe4E\x8f\x8eq\xe6\xd8\xfa\x02\x80I\xa9\x1c\xa3iK?\x01*%\x9dQ]\x87\xa6hP\x96\xf7\xc3\x067\x83\xe88\x1aO<]\xbd\xfd\xae\xfc\xfeM\xf9\xdd\x05\x80d=\xaeA+\xbeU\xdd\xd0\xe3\x86U\xf7\x83\xb6\xe5\x16;4\xaa\x14\xea\xc2j\xac\x88vcԠ\xd7pX\bg\xe3\xbd\x01\xf3\xad\xe2_<\x99w\x9e\x8c_\xe9\x84u\xffʭ\xfe(\xac\xf3;t7\x18\xd6-A\xf8E+d3t\xcc,\x96/\x00l\xa54\xae\xe1\x86`hV!\xbf\x00\x88O\xf4\xb0\n`\x9c{\xa6\xb1\xee\xd6\b\xe9\xd0\\\x11\x85Ĭ\x028\xda\xca\b\xed\x89\x1e\xe1\xa1E\t\xae\x15\x16\xc2k\xe1\x81Y\x82c\x9c\x7fe\xfeb\xbfNǭc\xbd\x9e \xb82\xc8\x0eG\x03\x04\xce\x1c\xe6\x00\xec\xf9\t\xaa\x06\xd7\"q\xde+\x16\x13R\xc8\xc6O\x05I\x80S\xb0A\x0f\x119\f:\x83LcUj\xc5K\x99\x88N`\xdd\xccf\xcf\xf1\x86\xf6\xff\xafQM\x00\xdd*\xfe\x02(Ϻ7l\x9e\xdc\xfae0\x96=\xff\xc6\xc40j/'X\x17\x8a\x11\x86\x0ff'$@\xe1\f\x84\x05\x16\x8f\x86W\x1c\x18\x9d\xdc\xd1ǿ\xdf}\x82t\xb5\x17Ɯ\xfb\x9e\uf1c3\xf6 \x02b\x98\x905\x995\t\xb16\xaa\xf74Qr\xad\x84t\xfeG\xd5\t\x94s\xf6\xdba\xd3\vGr\xff\xf7\x80֑\xacJ\xb8\xf2\x99\x02\xb9\xa7A\x93\xe6\xf2\x12\xae%\\\xb1\x1e\xbb+f\xf1\xab\v\x808m\vb\xec\xd3D0Nr\xe6\x9b\x03\xd7F\v)E9\"\xafY\xdeq\xa7\xb1\"\xe9\x11\x03館E\xf4P\xb52\xc0\xe6\xdb\xcb\t\xe1\xbc\xe1\xd2\xc8z\xa7\xf9\xa6\x19\xb2w\xb93\t\x9b\x1c\xf9\xd4\xe40\xc3\xce\x05Q\x80n\xeee\xf7g\fje\x85SfG\x84\x83\x83-\x17\x14\x8e\x88\x81\x86T\x1cϼ\xe3Fq\xcc\xc1\xa6\xa3\xe0Z\x16\xb4\x95\xf2+\xf2G\x83\x94\xcb[h(\xf9,`Z\xf13\xb8\xe2\x8d\f\f\xd6hPV\x98\x1cש\xe4!\x83l\x1c֗\x18\x8f+\x05\x9c\xf0\xeaY\xc4oo\xaf\x93'OL\x8c\xd8\xdd\xf2\xde3\xfc\xa1Q\v\xec\xb8\x0ft\xe7ᄐ\xae\xc3eާ9\x05\f\xb4\xc0\x90\x06\xee\x83\x04\bi\x1d2\x0e\xaa\xceR\xa4\x9a\x04\xc8\xf0\r\xc6\x13\xaf\x83\a\x8b\xae\xf2\x10Z\x88\xf7\xc0\xc8w\n\x0e\xff\xbc\xfbp\xb3\xfaG\x8e\xf5\xfbW\x00\xab*\xb4>\vvأt\xaf\xf7\x899G+\frJ\xb3\xb1\xec\x99\x145ZW\xc6;\xd0؟\xdf\xfc\x92\xe7\x1e\xc0\x0f\xca\x00>\xb2^w\xf8\x1aD\xe0\xf8\xde-'\xa5\x116\xb0cO\x11\x1e\x84k\xc5<\x98\xee9@\xea\x15\x9f\xfd\xe0\x9f\xeb\xd8=\x82\x8a\xcf\x1d\x10:q\x8fkx\xe5Ӛ\x03\xcc\xdf\xc8v~\x7fu\x84Ꟃi\xbf\xa2M\xaf\x02\xb8}\x1c\x1e\x1b\xdd\x01d\xb0<#\x9a\x06\x0fY\xd5|\xf8\xa0B\xae\xfa[P\x868 Ո\x84'L\xd2\v\x8e\x12\xf9\x02\xf4\xcfo~9\x8ax\xca/\x10\x92\xe3#\xbc\x01\x11K\x1b\xad\xf8\xb7%|\xf2ڱ\x93\x8e=\xd2MU\xab,\x1e㬒\xdd.\xe4\xb9[\x04\xab\xa8P®+B\x1e\xc4\xe1\x81\xed\x88\vIp\xa4o\f43\ue936\xa6\xec\xe7Ӈ\xf7\x1f\xd6\x01\x19)T\xe3=1E\xcdZP6CiL\x88\xc5^\x1b\x17\xc1<\r;\x04\xf5q\n\xaa\x96\xc9\x06\xc3{\x11ꁢcy\xf9\x12;^\xa6$idR\x93\xb9\xe3\xf8\xbf\x05\xf7'>\xceg\xd0Oxܸ\xca8\xf9\xb8\xfba\x83F\xa2C\xff>\xae*KO\xabP;\xbbR[4[\x81\x0f\xab\ae\xee\x85l\nR\xcd\"\xe8\x80]\xf92u\xf5\x8d\xff\xf3\xe2\xb7\xf8\x8a\xf6\xa9\x0f\x9aT\xda_\xf3Ut\x8f]\xbd\xe8Q)\x87}z\x1c\xbb\xbc\x8b\x99\xd5\xfc,\x99\xc5C+\xaa6\x15'\xd1\xc7\x1e1&A\x990\x0f\xae\x99\xc9\xddWWeb\xe8`\bѮ\x88\xbd\xb4\x82IN\xff[a\x1dͿ\x88\x83\x83x\x92\xf9~\xbe~\xff\xc7(\xf8 ^d\xabG\x12\xf00\x1e\x8b\x03\xac\xa2g\xba\b\xbb\x99S\xbd\xa8f\xbb)+\xbd\xe6\xc4\xf8Z\xa09\x93\xc6}\x9clN\x89f&\xbf\xdd\xefyV\x1e\xe9X\x93I\xdcƭ\xc3S\xe9\xddI~M\x1b7\xac\xb1\xc0\f\x02\x83\x9ei\x92\xf3=\ue290\x10h&(\x9aS\xc0\xdewE\x80i݉l\xe0\x8ea?\xa6\xac\x91\x13T\x96\xb3\xc6\x1e{{Vj\xe3.\xd0\x19)|\x1emM28Ӈrmή'ݩ%Z\x94C\xbf\x84R\xc0\xbd҂e\xe6\rZ\xb7\xd0/Zx\xb5\xccKN\b+\xf0\xf2\f\x0fb{8S\xeaDQ\x84\xbcp_\xee\xf8\x8e`\xae\x9e8^L\x1c\x85H\xf5a\x89=Z˚s\xa6\xf8S\xd8\x15\xea\xfbx\x04\xd8F\rn_\xe0O\xdc㥍:\xf5\xbc\x1eC\xb6t\x9e\xaa3\xa3\xd2\xc6\xc6\x14\xbf\xeb\xfc\x99\xb1#8|\x93\xf3\xa86\x98O\x11^\xe2\x13\x00\xfcǦs\biO\xce\xc0\xf6\xde뤅\xc1\t\xa7|\x83\x0f\x99\xd9\xc5G\xb2\xf1\xe2U2\x99\xcc\xda\x0f\xde\x1a\x9e\xf5\xfex\xd19\x16\xc4mЪ.\x19\xb3r\xac\x039\xf4\x1b4ć\xcdΡ\x9d\xba\xf3\\7\xc7W\x81\a6\x8e\xce'\xf9\x05J\xb1\xb0\xad\x98\xf4]W\xb2.\xa7\x80\v\xab;\xb6\xcb\x10N\x0f\xf1\x99\x1e\x19\x17\xb9\x80\x83>'\xa3\xd6h\xfc\xd2s\xbbP\x1e\xd3{%\x8f\xd4%ɞ\x85t\x7f\xfdˉ\xbcPH\x87\xcd,8\xc4ub\xe7;\xba\xe5\xeb\xdcp\"\x89\xb1\x92i\xdb*w\xfd\xfe\x8c\x16\xdc\xed7&k8\xa4\x8c\xde\xf7\xf9\x9ep\xdc\x14U!'\xaa\xbdoy\x96\xa9N?Ϟ\x83:\xd9|&\n\xc5\x0fù\x18t\x87\x9a\x19\xb2t\xff\x05\xe1j\xfe\x89\xeb5X\xe1ۢ\x94y\x86T44-,\x05'J\xad\x94\xc1\x8c˄eX\x99\x04\x91)\xfc?2~d\xf5d1\xe9\x91\xf3\x11\xed\xd8Z\x1f\xcf\f\x9b\xfdg\xa35\xfc\xf6\xfb\xc5\x7f\x03\x00\x00\xff\xffY\xc0\xfaX\xc0!\x00\x00"), + []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xc4YKs\xdc6\xf2\xbf\xebSt9\a\xfdSerb\xff\xb7\xb6\xb6\xe6f\xcb\xeb-\xed&\xb2ʒ}I\xe5\x80!\x9a$\"\x12@\x00p\xa4\xd9T\xbe\xfbV\x03\x04\x87\x0f̌F\xb5\xce\xf2\"\r\x1e\xdd?4\xfa\x8d,\xcb.\x98\x16_\xd1X\xa1\xe4\x1a\x98\x16\xf8\xe4P\xd2/\x9b?\xfc\xcd\xe6B\xad\xb6o.\x1e\x84\xe4k\xb8\xea\xacS\xedg\xb4\xaa3\x05~\xc0RHᄒ\x17-:ƙc\xeb\v\x00&\xa5r\x8c\x86-\xfd\x04(\x94tF5\r\x9a\xacB\x99?t\x1b\xdct\xa2\xe1h<\xf1\xc8z\xfbC\xfe\xe6m\xfe\xc3\x05\x80d-\xaeA+\xbeUM\xd7\xe2\x86\x15\x0f\x9d\xb6\xf9\x16\x1b4*\x17\xea\xc2j,\x88veT\xa7װ\x9f\b{{\xbe\x01\xf3\xad\xe2_=\x99\xf7\x9e\x8c\x9fi\x84u\xffJ\xcd\xfe(\xac\xf3+t\xd3\x19\xd6,A\xf8I+d\xd55\xcc,\xa6/\x00l\xa14\xae\xe1\x86`hV \xbf\x00\xe8\x8f\xe8ae\xc08\xf7Bcͭ\x11ҡ\xb9\"\nQX\x19p\xb4\x85\x11\xday\xa1\xdc*\x0e\x01 \x04\x84`\x1ds\x9d\x05\xdb\x1550\v7\xf8\xb8\xba\x96\xb7FU\x06m\x80\a\xf0\xabU\xf2\x96\xb9z\ryX\x9e\xeb\x9aY\xecg\x83x\xef\xfcD?\xe4v\x04\xda:#d\x95\x82q/Z\x84\xc7\x1a%\xb8ZX\b\xa7\x85Gf\t\x8eq\xfe\x94i\xc6~\x9e\xb6[\xc7Z=Ape\x90\xed\xb7\x06\b\x9c9L\x01\x18\xe4\t\xaa\x04W#I\xde+\x16\x13R\xc8\xca\x0f\x85\x9b\x00\xa7`\x83\x1e\"r\xe8t\x02\x99\xc6\"\u05ca\xe72\x12\x9d\xc0\xba\x99\x8d\x9e\x92\r\xad\xffo\xa3\x9a\x00\xbaU\xfc\x05P\xce\xe2\x1b\x16O\xb8~\x1d\x0f\x9dԏ\x1a\xfd\x9aȼӍb\x1c\r\xb1\xaf\x99\xe4\r\xd2\xcd2p\x86I[\xa29\x00#n\xbb\xdf\xe9)\x98/\x91\xdeh\xe6\x1ca\xf4\xb6s\xe7\x94a\x15\u008f\xaa\xf0\x0e\x8aT\xda\xe0D\xa7m\xad\xba\x86\xc3&r\x01\xb0N\x99\xa4\x82\x13Ⱛ\xa7\x1b\xc9\xce\xecl\xca\xf30\xfa\x11\xed\xe8O\xf3\x82lD(\x99\xb6\xa0w\x15\xa6\xad'Lo\xdf\x04wU\xd4زu\xbfRi\x94\xefn\xaf\xbf\xfe\xff\xddd\x18@\x1b\xa5\xd18\x11\xddg\xf8F\xc1a4\nSQ_\x12\xc1\xb0\n8E\x05\xb4A\a\xc3\x18\xf2\x1eC\xb8\x0ea\xc1\xa06hQ\xba\xb1H\xe2\xa7J`\x12\xd4\xe6W,\\\x0ewh\x88L\xbc\x98B\xc9-\x1a\a\x06\vUI\xf1\uf076%]#\xa6\rs\xd8{\xf1\xfd\xe7\x1d\xadd\rlY\xd3\xe1k`\x92C\xcbv`\x90\xb8@'G\xf4\xfc\x12\x9b\xc3O\xca \bY\xaa5\xd4\xcei\xbb^\xad*\xe1bP,T\xdbvR\xb8\xdd\xca\xc77\xb1\xe9\x9c2v\xc5q\x8b\xcdʊ*c\xa6\xa8\x85\xc3\xc2u\x06WL\x8b\xccC\x97>0\xe6-\xff\xce\xf4a\xd4^N\xb0.\x14#|>\x98\x1d\xb9\x01\ng ,\xb0~k8\xc5^\xd0\xd1\x1d}\xfe\xfb\xdd=D\xd6\xfe2\xe6\xd2\xf7r\xdfo\xb4\xfb+ \x81\tY\x92Y\xd3%\x96F\xb5\x9e&J\xae\x95\x90\xce\xff(\x1a\x81r.~\xdbmZ\xe1\xe8\xde\x7f\xeb\xd0:\xba\xab\x1c\xae|\xa6@\xee\xa9Ӥ\xb9<\x87k\tW\xac\xc5\xe6\x8aY\xfc\xe6\x17@\x92\xb6\x19\t\xf6yW0Nr拃\xd4F\x131E9p_\xb3\xbc\xe3NcA\xb7G\x02\xa4\x9d\xa2\x14\xbd\x87*\x95\x016_\x9eO\b\xa7\r\x97\xbe\xa4w\x9a/\x9a!{\x9f\xda\x13\xb1ɑO\x8d\x0e3\xac\\\x10\x05h\xe6^v\xd8cP++\x9c2;\"\x1c\x1cl\xbe\xa0p\xe0\x1a蓊\xe3\x89s\xdc(\x8e)ش\x15\\͂\xb6R~E\xfe\xa8\x93rɅ>%\xcf\x02\xa6\x15?\x81\xab\xe7\xc8\xc0`\x89\x06e\x81\xd1q\x1dK\x1e\x12\xc8\xc6a}\x89\xf1\xb0R\xc0\x11\xaf\x9eD\xfc\xee\xf6:z\xf2(\xc4\x1e\xbb[\xf2=!\x1f\xfaJ\x81\r\xf7\x81\xee4\xef\xcb\xeb20\xf3>\xcd)`\xa0\x05\x864p\b\x12 \xa4u\xc88\xa82I\x91j\x12 \xc37\xd8\xefx\x1d\xad\x032R\xa8\xca{b\x8a\x9a\xa5\xa0l\x86Ҙ\x10\x8b\xbd6.\x82y\xfcl\x17\xd4\xc7)(j&+\f\xe7E(;\x8a\x8e\xf9\xe5K\xecx\x99\x92\xc4/\x91\x9a\xcc\x1d\xc7\xff,\xb8?\xf3p>\x83~\xc6\xe1\xc6U\xc6\xd1\xc3=t\x1b4\x12\x1d\xfa\xf3qUX:Z\x81\xdaٕڢ\xd9\n|\\=*\xf3 d\x95\x91jfA\a\xecʗ\xa9\xab\xef\xfc\x9f\x17\x9f\xc5W\xb4\xcf=Ф\xd2\xfe\x96\xa7\">v\xf5\xa2C\xc5\x1c\xf6\xf9q\xec\xf2\xaeϬ\xe6{\xc9,\x1ekQԱ8\xe9}\xec\x01c\x12\x94\t\xf3\xe0\x9a\x99\xdc}sU&\x81v\x86\x10\xed\xb2\xbe\x97\x961\xc9\xe9\x7f+\xac\xa3\xf1\x17I\xb0\x13\xcf2\xdf/\xd7\x1f\xfe\x1c\x05\xefċl\xf5@\x02\x1e\xbe\xa7l\x0f+k\x99\xce\xc2j\xe6T+\x8a\xd9j\xcaJ\xaf9\t\xbe\x14hN\xa4q\x9f'\x8bc\xa2\x99\xc8o\x875g呎U\x89\xc4m\xdc:<\x96\xde\x1d\x95״q\xc3*\v\xcc 0h\x99\xa6{~\xc0]\x16\x12\x02\xcd\x04Es\n\xd8CW\x04\x98֍H\x06\xee>\xec\xf7)k/\t*\xcbYe\x0f\x9d=yk\xb1\vt\xa5d)\xaa\x13\xf7\xf0e\xb2x\xc8\tlL;JQuf_J\x8d\x9bS\xe7&͚\x19\xd64\xd8|\x14\r\xda\xc0\xf7\x19\xf6s\xbb\xdc5\x94%]\xbbACB/ir`p\xc0\xef\x04\xdc>\xbf\xd2hJe\xdaВ\xedl,\x17\x0e\x9fl/r!\x1dVC\a\xee\xac\v\xb9\xa7%ϻ\x0eZ\x1a\x8fy\xa21\xe8ꔣ\x9d\xb4\v\x97\xe7AٵK(\x19<(-Xbܠu\v\x83\xa7\x89W\xcbD\xf1\x88\xf5\x04\xe5>!\x83\xbe_\x9f\xa8={\xdb\b\x89\xfaP\x7f\xfa\x16m\xaa\xc0;\\\xdd\x1d\x84h\xf0\xb7\x8eʎ)\xc4,\xdd\t\x98\xad\xa1\xcax6\xa4\x15\xbf\x98\vr\xec\xf7f\x93\x936\xf2\x18\xe9\xb2=\xe2_\a\xceh\x90\x84W\x8f^\xa6!\x1c\xba\xf8\x16B\xb5\xe0K[$\x85\xa22k\xd2b=q\xbdW\xcb\x1d\xbe\x1bix\xaf\xee\xa2%w:z#\xe9y\xa4z\x1c0\"\x17v\xfa\x04\x84\xa8!\xf75\x10\x95h%\x13\rr\x88\x0fa\xf3=\t\xaac*\x1b,)Z\aӋ\xae\xa2\x877\xd4\x195\x82\xf5m\xbeK{\x84fg\x91{?\x9a\x10²\xf6 \x17\xc5\\hKgI\xa2\xb2k\x1a\xb6ip\r\xcet\xcb\xe9#\x96آ\xb5\xac:e\x8a?\x85U\xa1\xe1\xd2o\x01\xb6Q\x9d\x1b:.\x93xui{\x9d:\xaf\xe9\x93\xece̢\x00՚\xb6\xaf\xb9\x9a\xc6\xef\x19;\x82\xfd#\xa9G\xb5\xc1t\xce\xf6\x12\x9f\x00\xe0_\xffN!\xa45)\x03\x1b\xbc\xd7Q\v\x83#N\xf9\x06\x1f\x13\xa3\x8bW\xcb\xf1\xe4U4\x99\xc4\xdcGo\rg\x9d\xbfgtJ\x04\xfd2\xa8U\x13\x8dY9\u058c\x02\xf5f\xe7\xd0N\xddy\xaa\xbd\xe6\xcb\xf2\xbd\x18G\xfb\xe3\xfd\x05J}\xa7\xa1`ҷ\xc1ɺ\x9c\x02.\xacn\xd8.\x95\x82D\x84\x94z\x93q\x91\v\xd8\xebs4j\x8d!\xe597\xc3\xf1\x98>(y\xa0P\x8c\xf6,\xa4\xfb\xeb_^\x90b@\x10\xe7{\xe2\xf2m8\x1cIb\xacd\xda\xd6\xca]\x7f8\xa1\x05w\xc3\xc2h\r\xfb\x1c~\xc8!#\xb5^\x15RW5\xf8\x96\xb3Lu\xfa^~\n\xead\xf1\x89(Կԧb\xd0\x1dR\xea\xe90<\xe9\\\xcd\xdf\x1c_\x83\x15\xbeOM\xa5@\xa8\rB\x17\xc9Rp\xa2\xd4J\x19L\xb8LX\x86\x95I\x10\x99\xc2\xff3\xe3GRO\x16\x83\x1e9\x1f\xd1\xee\xdf:\xc6#\xddfx\xc7[\xc3\xef\x7f\\\xfc'\x00\x00\xff\xffo\x05\xb2\xa4Q#\x00\x00"), []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xc4Y_\x93۶\x11\x7fק\xd8q\x1e\xae\x991\xa9\xd8\xedt:z\xb3\xef\x9aε\xc9Yc\x9d\xfd\x92\xc9\x03D\xacHD$\x80\x02\xa0tj&߽\xb3\x00A\xf1\x9f\xa4\xd3M.\xe1\x8b}\xc0b\xf1\xc3\x0f\xfb\x0f\xab$IfL\x8b\xafh\xacPr\x01L\v|r(\xe9/\x9bn\xffaS\xa1\xe6\xbbw\xb3\xad\x90|\x01\xb7\xb5u\xaa\xfa\x8cV\xd5&\xc3;\xdc\b)\x9cPrV\xa1c\x9c9\xb6\x98\x010)\x95c4l\xe9O\x80LIgTY\xa2Ir\x94\xe9\xb6^\xe3\xba\x16%G\xe3\x95ǭwߥ\xefާ\xdf\xcd\x00$\xabp\x01Z\xf1\x9d*\xeb\n\rZ\xa7\f\xdat\x87%\x1a\x95\n5\xb3\x1a3R\x9e\x1bU\xeb\x05\x1c'\xc2\xe2f\xe3\x00z\xa9\xf8W\xaf\xe7s\xd0\xe3\xa7Ja\xdd\x7f&\xa7\x7f\x10\xd6y\x11]ֆ\x95\x138\xfc\xac\x152\xafKf\xc6\xf33\x00\x9b)\x8d\vx (\x9ae\xc8g\x00\xcd9=\xb4\x04\x18\xe7\x9e9V.\x8d\x90\x0e\xcd-\xa9\x88\x8c%\xc0\xd1fFh\xe7\x99i\xf5\x80ڀ+\x90\xb6\xf4\xac2!\x85\xcc\xfdP\x80\x00N\xc1\x1a\xa1A½2\x80_\xac\x92K\xe6\x8a\x05\xa4D\\\xaa\x15Oe\xd4\xd9\xc8\x04\xce\x1f\x06\xa3\xee@\xe7\xb0\xce\b\x99\x9fB\xf6;\x83\xea\xe1Y*\xfeL$\x8f\x05z\x99\x88\xa6֥b\x1c\rm^0\xc9K\x042Pp\x86I\xbbAs\x02E\\\xf6x\xd0}$_\xa2\xbe\xce\xcc5\xec\\CE\x90\xedm\xff\xb5;tiߥ\xe2\xcd\x02h\x8c\x1a\xacc\xae\xb6`\xeb\xac\x00f\xe1\x01\xf7\xf3{\xb94*7h\xed\x04\f/\x9e\xea\x82\xd9>\x8e\x95\x9fx]\x1c\x1be*\xe6\x16 \xa4\xfb\xfb\xdfNck\x16\xa5N9V~<8\xb4=\xa4\x8f\xc3ဖ\x9c-o\xae\xffO\x81\xbb&HwJ\xf6y\xfd8\x18\x9d\x02\xdbQ\x1a\xe3m\x9a\x19\xf4\xa1\xf6QTh\x1d\xabtO뇼\xaf\x8f3\x17\x06\xc2\xf4\xee]\beY\x81\x15[4\x92J\xa3\xfc\xb0\xbc\xff\xfa\xd7Uo\x18@\x1b\xa5\xd18\x11\xa3k\xf8:ɣ3\n}foHa\x90\x02NY\x03mp\x8a0\x86\xbc\xc1\x10\x9cEX0\xa8\rZ\x94!\x8f\xf4\x14\x03\t1\tj\xfd\vf.\x85\x15\x1aR\x03\xb6Pu\xe9#\xd0\x0e\x8d\x03\x83\x99ʥ\xf8_\xabے\xefѦ%s\u0604\xf8\xe3\xe7c\xb0d%\xecXY\xe3[`\x92C\xc5\x0e`\x90v\x81Zv\xf4y\x11\x9b\u008fd!Bn\xd4\x02\n\xe7\xb4]\xcc\xe7\xb9p1if\xaa\xaaj)\xdca\xee\xf3\x9fX\xd7N\x19;\xe7\xb8\xc3rnE\x9e0\x93\x15\xc2a\xe6j\x83s\xa6E\xe2\xa1K\x9f8ӊ\x7fc\x9a4kozXGN\x17>\x9f\xeb\xce\xdc\x00%;\x10\x16X\xb34\x9c\xe2Ht\fٟ\xff\xb9z\x84\xb8\xb5\xbf\x8c!\xfb\x9e\xf7\xe3B{\xbc\x02\"L\xc8\r\x05]\xbačQ\x95\u05c9\x92k%\xa4\xf3\x7fd\xa5@9\xa4\xdf\xd6\xebJ8\xba\xf7\xff\xd6h\x1d\xddU\n\xb7\xbe\x92\xa0xYk\xb2\\\x9e½\x84[Vay\xcb,\xbe\xfa\x05\x10\xd36!b\x9fw\x05\xdd\"h(\x1cX\xebL\xc4\n\xe6\xc4}\r\xab\x92\x95ƌ\xae\x8f\x18\xa4\xa5b#2\xef\x1b\x14~\x80\x8d\xe4Ӟ\xeaiץoͲm\xadWN\x19\x96\xe3\x0f*\xe8\x1c\n\r\xb0}\x9cZ\x13\xc1\xc9N\xce\v\xca\xc1\x06ɑR\x802.\xde\x17h\xb0\xbbƠVV8e\x0e\xa48d\xcbt\xa4\xe1\xc4E\xf8#+~\xe1\x18\x14\xee\xbdC\x18ܠA\x99a\x8c\x10\xe7*\x99\x89St\x12\xfa\x18\xe2i\xea\xe1L\xf4\x9c\x04\xfcay\x1f#fd\xb8\x81\xee\xc6\xfb^\xa0\x87\xbe\x8d\xc0\x92\xfb\x84ry\xef\x9b\xfbM\xd8\xcc\xc7\x0e\xa7\x80\x81\x16\x18*\xd26\x18\x83\x90\xd6!\xe3\xa06\x93\x1a\xe9m\x00\xe4`\x06\x9b\x15oC\xa4hB\xd21\x84\x13\xf5\xc0(F\t\x0e\xff^}z\x98\xffk\x8a\xf9\xf6\x14\xc0\xb2\f\xad\xf5\xf9\x1a+\x94\xeem\x9b\xb39Za\x90S\xe1\x82iŤؠui\xb3\a\x1a\xfb\xd3\xfb\x9f\xa7\xd9\x03\xf8^\x19\xc0'V\xe9\x12߂\b\x8c\xb7\xe1/ڌ\xb0\x81\x8eV#\xec\x85+\xc40i\xb5\f\x90u5\xc7\xde\xfb\xe3:\xb6EP\xcdqk\x84Rlq\x01o|%x\x84\xf9+9\xd6ooNh\xfdKp\xa07$\xf4&\x80k\xf3]\xd7#\x8f ]\xc1\x1c8#\xf2\x1c\x8f\x85\xe8\xf0\xf3\xc1\x9bBⷠ\f1 UG\x85WL\xb7\x17\xe2\x11\xf2\x11\xe8\x9f\xde\xff|\x12q\x9f/\x10\x92\xe3\x13\xbc\a!\x037Z\xf1oSx\xf4\xd6q\x90\x8e=\xd1NY\xa1,\x9ebV\xc9\xf2\x10\xaa\xfd\x1d\x82U\x15\xc2\x1e\xcb2\t\xf5\x06\x87=;\x10\v\xf1\xe2\xc8\xde\x18hf\xdcYk\x8dU\xc6㧻O\x8b\x80\x8c\f*\xf7\xf1\x8e\xb2\xd3FP\xd5@\xe5B\xc8y\xde\x1aGI3~\xb6\x0e\xe6\xe3\x14d\x05\x939\x86\xf3\"lj\xcaB\xe9\xcdK\xfcx\x9c\xfa\xe37Q\x02\f\x03ǟ\x96D\x9fy8_\xa9>\xe3pݷ\xd6\xd9\xc3m\xeb5\x1a\x89\x0e\xfd\xf9\xb8\xca,\x1d-C\xed\xec\\\xed\xd0\xec\x04\xee\xe7{e\xb6B\xe6\t\x99f\x12l\xc0\xce\xfd\x93y\xfe\x8d\xff\xe7\xc5g\xf1\xaf\xeb\xe7\x1e\xa8\xf7\xe8\x7f\xcdS\xd1>v\xfe\xa2C\xc5Z\xf1\xf9y\xecf\xd5\x140õ\xe4\x16\xfbBdE|\x0441\xf6\x843\t\xaa8y\b\xcdL\x1e^ݔ\x89\xd0\xda\x10\xa2C\xd2\xf4\xb4\x12&9\xfd\xdf\n\xebh\xfcE\f\xd6\xe2Y\xee\xfb\xe5\xfe\xee\x8f1\xf0Z\xbc\xc8WO\x14\xba\xe1{J\x8e\xb0\x92\x8a\xe9$H3\xa7*\x91\r\xa4\xa9\xf6\xbb\xe7D\xfcF\xa0\xb9P\xc5}\xee\t\xc7*t\xa2\x8ale\xae*#\xadd\xda\x16\xca\xdd\xdf]\xc0\xb1j\x05#\x86\xe3u5\xc5c\xd45h\x02]\x87\xc7\xfb\xcb\xc3\xe9@\xd2\a\u0557\x8eȔ\x11\xb9O[\xad\xef\xfbW\x84d\x15\xeb6\xff\xba_Ŵ\x162\xbf\nk\xb7\x97v\x01藎hDy\xa1\x9b\xe7\x8a)\x9c\xbd\x1e\xdf\x18-ʺ\x1aCI`\xab\xb4`\x13\xe3tG#\xfb\xa4\x897\xe3\xba\xe6\f\x13\xc1\x00.pд\x9e&\xdeQ\x8d\xfd\x84\xbaҏ\xd0\xdb\xc5[\xd1t@\xbe֮\xe8\xd9MEr\x1fa2\xfd:\x1c\xc8h\xc5gCҺ.9\x98<:\xd4p\xa2o\xab\x83\xd9^K\xb4{\x9a\xf1\xc3\xda\xf7ۮyZ\x87\x1e_\xc3{\x88\xf0.v\xfe\xe8y\xf3\xe2\xc7u\xa6\xe8\xe9\xd0k\xcf]\xb0\x81\xdb\xf1\n\xdf\xc92\xbc\xf1\tQ\xa1\x7f\xb1\x86\xf6\xe4\x9eٸ\xc9\xd4}CG_X\xea\xb3*\xa9C\xee\v{zwl\x98(\x91C\xfb+\x8bo\xa5[\xdfҹ\x99\xaac\xa3\xa2\xda\"\xf7qc\x02\xf4x]\xec\x92r\xe60!\x15#\tY\x97%[\x97\xb8\x00g\xea\xf1\xf4\x19\xf7\xaa\xd0Z\x96_\xf2\xaf\x1f\x83Tx\xf37K\x80\xadU\xed\xdaG\x7f\xe3h\r\x157\xb6\xb1\x82\xeb\x1a\x0f\x05\xb3\x97\xa0,If\xca\xe2Z\x97?orp&\x94=\xe0~btԵ\xeeN\xdeF\x13\x9a\x98\xfb\xde[\xc7U\x044\x1b]\xe2\xa0\x11\x83B\x95Ѻ\x95\xa3\xa4TWk4D\x84o\x95GFb\xe0\x98\xea\xa2\xf8\xd7בɣ\x86\x18\v\x83\xaa\xe6=\x991雊d\xbfN\x01\x17V\x97\xec0\xa17\x9e\xc4\x17Xd\xbe\xe4GG\x8b\x89^H\xee\xef\xe7\xae\xed\xfe\xb4?\x05L\x97\x7fS?,L\xddB\xf7W\x82\xc1|\xfb\x1b\xc8\xeb\xecp\xa6䳎\x19\xf7ܰ\xb7\xea\t_\x8ax^\xf5t\xbc놮q\xa0\xeao\xf3GƨI\xa2F\x83\x1e9\xef\xe8n:\xa7ݑz\xdd\xfe.\xb0\x80_\x7f\x9b\xfd?\x00\x00\xff\xffg\b\x17r\xc1\x1f\x00\x00"), []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xdc]O\x93\xdb:r\xbfϧ@9\a'U#y\x9d\\Rs\x9b\xf8\xd9Ye\xf7\xd9Sc\x97\xdf\x19\"[\x12vH\x80\x0f\x005VR\xf9\xee\xa9n\x80\xe0\x1f\x81$\xa8\x19\xbd\xf5\x06\xb7\xa1\x80\x06\xd0\xddht7~\xc0\xacV\xab\x1b^\x89\uf80dP\xf2\x8e\xf1J\xc0\x0f\v\x12\xff2\xeb\xa7\x7f7k\xa1\xde\x1d\xdf\xdf<\t\x99߱\x0f\xb5\xb1\xaa|\x04\xa3j\x9d\xc1/\xb0\x13RX\xa1\xe4M\t\x96\xe7\xdc\xf2\xbb\x1bƸ\x94\xcar\xfcl\xf0O\xc62%\xadVE\x01z\xb5\a\xb9~\xaa\xb7\xb0\xadE\x91\x83&\xe2M\xd7\xc7?\xad\xdf\xff\xeb\xfaO7\x8cI^\xc2\x1d\xd3`\xac\xd2`\xd6G(@\xab\xb5P7\xa6\x82\fi\ued6a\xab;\xd6\xfe\xe0\xda\xf8\xfe\xdcX\x1f]s\xfaR\bc\xff\xd2\xfd\xfaWa,\xfdR\x15\xb5\xe6E\xdb\x19}4B\xee\xeb\x82\xeb\xf0\xf9\x861\x93\xa9\n\xee\xd8g\xec\xa6\xe2\x19\xe47\x8c\xf9\xa1S\xb7+?\xea\xe3{G\";@\xc9\xddx\x18S\x15\xc8\xfb\x87\xcd\xf7\x7f\xfb\xda\xfb\xccX\x0e&Ӣ\xb2\xc4\x00?6&\f\xe3\xec;\xcd\r\a@\xbcf\xf6\xc0-\xd3Pi0 \xada\xf6\x00\x8cWU!2bu\xa0ȘڅV\x86\xed\xb4*[j[\x9e=\xd5\x15\xb3\x8aqf\xb9ރe\x7f\xa9\xb7\xa0%X0,+jcA\xaf\x03\xadJ\xab\n\xb4\x15\rc]\xe9\xa8K\xe7\xeb`.oq\xba\xae\x16\xcbQO\xc0\rٳ\fr\xcf!\x1c\xad=\b\xd3Nm8\x1d?%.\x99\xda\xfe\r2\xbbf_A#\x19f\x0e\xaa.rT\xaf#hdN\xa6\xf6R\xfcw\xa0mp\xa2\xd8i\xc1-xy\xb7EH\vZ\xf2\x82\x1dyQ\xc3-\xe32g%?1\r\xd8\v\xabe\x87\x1eU1k\xf6+\x89G\xee\xd4\x1d;X[\x99\xbbw\xef\xf6\xc26\xcb$SeYKaO\xefH\xe3Ŷ\xb6J\x9bw9\x1c\xa1xg\xc4~\xc5uv\x10\x162[kx\xc7+\xb1\xa2\xa1KZ*\xeb2\xff\xa7 \xb6\xb7\xbd\xb1\xda\x13j\x9e\xb1Z\xc8}\xe7\aR\xf3\t\t\xa0\xc2;]rM\xdd,ZF\xe3'\xe4\xce\xe3ǯߺz&̐\xfb\xc4\xf7\x8e\xf2\xb5\"@\x86\t\xb9\x03\xed\x84Hچ4A\xe6\x95\x12\xd2\xd2\x1fY!@\x0e\xd9o\xeam),\xca\xfd\xf7\x1a\f*\xb4Z\xb3\x0fd;\xd8\x16X]\xe5\xdcB\xbef\x1b\xc9>\xf0\x12\x8a\x0f\xdc\xc0\xd5\x05\x80\x9c6+dl\x9a\b\xbafoX\xd9q\xad\xf3Cc\xbcF\xe4\xe5W\xff\xd7\n\xb2ފ\xc1fb\xe7\x979\xdb)\xdd3\x0e\xd8d\xdd#\x1a_\xb4X\xdc\xeaG\v6\xfce0\x94\xff\b\x15Q\x7fp\x10\xb5\x14\xbf\xd7@&έX83)g$Y3>R\x8b\xf5\xd9\xef#<\xc5\x02?\xb2\xa2\xce!\x0f\xd6\xf6l.\x83\x11\x7f\xe7d\n?]I\xb1\x95#|\x8cX;\xfa\xb7\x13\x9b \xc9P͟\x0f\";8'\x00u\x93\xe8\xb0\\\x81!Á\x8e\xeail\x92lN\xf6\xbe\x93)\xd3і\x9955\xa4\x173'mI0\xb7m\x991\xbcg\x86\xc5\x7f\x8f\xee\x9cm\xf9\xff\xc9\xd8f'\xb9@i7gM_Wi)\xa8Bg\x7f\xb3cPV\xf6t˄m\xbe\xceQ\xe4E\xd1\xe9\xff\x1fX0\xcb5~3l\xf9\xaa\x1a?)\x959\x8a(\x95\xd0\xfd?\xa0Ph\xb3\xf8\xea\xf7\x8ad\x81\xfc\xb5\xdbꖉ]\x10H~\xcbv\xa2\xb0\xa0\a\x92y\xd1zy\rf\xa4\xecwXJn\xb3\xc3\xc7\x1f\xe8٘6ϔȗac\xe7\x1271B\x7fc\x9e\xa1\xcb(|\x15\x1aJ\x17\x16\x7f#n\xb6_(\x9e\xb8\xff\xfc\v\xe4S\xecai\x9aw6\x91\xfb\xc1`\xbb]{??u\x1a\xde\xf5\t1\x93Kx\xdc2Ξ\xe0\xe4<\x16.\x19\n\x87[\xf2w\xa3\xd1\xd39s(\xf3BJ\xf6\x04'\"\xe3S)\xb3\xadSU\xc1\x95'\x88\xb8\xfb\xb1\xd2c \x8e\xc9\a\xb8\x8e\x93\xf8\x81\x18A\x81w:\xf3\x18\xa5\xc5\x1a[4?9\x96nH\x9a\xd2\xf0\xfe\x82i\x06\xb1u҇$طƉ\bW\xc1AT\x89\x13\xa5\xec\xa1\x01Z-Mb\xec;/D\x1e:rz\xbf\x91\xe3\xdep\xbf|Vv#o]DfHK~Q`>+K_\xae\xc2N7\xf0\v\x98\xe9\x1a\xd2\xf2\x92\xcel#\x1f\xba\x19\xb6\x04\xe5ve\xe3\x12)A<°\x8d\xc4\xc0\xc5\xf3\x83\U000a5bbb\xe9\xfd\xa1_\xca\xdaP\nM*\xb9\xa2\xadr\x1d\xeb\xc91;\x91\xa4\xd2=\x89\x9c\x0f-t\xea:L$\xfb\rw\x12\xd7\xdee\x80\v\x9eA\xdeD\x9b\x94\xb7\xe4\x16\xf6\"c%\xe8\xfd\xd4\xc6\xd1-\x15\xda\xf7\xb4!$Z]W\x16jX\xda\xd6\xde\x14o\xba\xf3\xf9\xc1\xacp\xe5&\xd4j\x84=[u$]9^u~F\xb4Œ\xff1\xcb]\x9e\xe7t\x84ċ\x87\x05\x16\x7f\x81,\xce\xf7~70\xb7C\x96\xbc\xc2\xf5\xfb?\xb8͑B\xff/\xab\xb8\xd0\tk\xf8\x9e\x8e\x89\n\xe8\xb5\xf5\x89\xb1n7\u06030\f\xe5{\xe4\xc5y\"<29\x85\xb6\x05\n\xb7\x91\xabݙ\xc7r˞\x0fʸ=u'\xa0\x88\xa5l\xfaE\x18\xf6\xe6\tNon\xcf\xec\xc0\x9b\x8d|\xe36\xf8\xc5\xe6&x\vJ\x16'\xf6\x86ھy\x89\x13\x94\xa8\x89\x89\xd5~\xac\x9eBJnU\xf2j\xe5\xb5תRd\xa3\xedd4=ޖ\x9e:uS\xe4mnܻ\xc7S\xb3M\xd2\xdfJ\x19\xfb\xe7x\xa2od<\x0fM\x8b\xbeO\x1bɗ\xcd\xfa\xfa>\xf7\x15\x8c1z\x80;\v\xda'\xff\x9c\x81n\"\x87\x17\xc6Tsɽ\x90\xd8\xe3!!\x8b\f\x9e\xd1&wT\x922\xc4%\xde&\xf2e\xa1\x9f\xfe\xf1G'7\x89+\x1b\xff\xeeN䵽\xe1L\x95%\x1f\x1e\x0e&\r\xf5\x83k\xd9\xe8\xb4'䤯\xf75\xad\xe7t7\xb1\xd1!:\x16|\x16\xf6 $\xe3\x8d\xd9\x00\xed\x15\x8a\xb3J\xcd[0W\x0eܰ-\x80\f9\xf5\x9fa\x9f/\x85\xdcP\a\xec\xfd\xab\xfb\x05\xace\xd7E\xe2lX\x1d\x04\x1a>\xd0N\x95\xeaR\xa9\x9c=\x1f@CO+\xce\x13\xe5\xe8i&\x92\x94\xcav\xf3\x11H\xb7R\xf9[\xc3vB\x1b\xdb\x1dh\xaa\xc2\xd5&U\x1d\x16J\x18g\xf7M\x94\xa0j{\x81\f>\xb6\xad{\xe7\xba%\xff!ʺd\xbcTu\x82S\xe0\n\xee/\xa2\f\x87\xaf^\x02\xcf\\\xd8p\x0eE\x99\x19\xabPJU\x016U\xc4[ء9ʔ4\"\a݀\x03\x9cd\x85\u0085\xbb㢨c\xc7>\xb1\xb24\xbc\x95\x1f\xb5\xbe(\xba\xfd\xe2Zv\xb2\x8d\a\xf5\xdcgP2\v\x0e\xfc\bL옰\fd\x86r\x01\xedL6u\xe1\x99A\xacIV\xcb4\x03\x8f\x05d]\xa61`E+[\xc8\xc9dZ\xb7\xfa'.\x8ak\x88\r5\xef\x93ҏ\xc0\xf3K\x120\xbfu\x9a3\x90\xa6\xd6tp\xef\xcc˳(\xd2ƌ\x92c\x05\xafev\x00\xb2S\xb2g>\x98#/\xa4\xb1\xc0Su\x01\xbd\xa6ZJ!\xf7i\xb2KNq\xb6űz\xabT\x01|\bx\x8a\x15\xe4\xf5\xe5f跶\xf5\x1fb\x86\x82\x04\xd2݅-xQy[ĭ\x85\xb2r\xebM1]\xcb\xee\xees\x05+\xb4$\x06\xf7\xa3x\xcd\xe0ZH\x91 \xd8\xc1\x99\x8b\xb0]\xcf\x12I\\ճ\xc4\x0e\x82SqI\xfal\xd3#\x80\xab\xb3\tRh\xecAk\x16x\x99[`<\xcf!w\x89ItU|\xcc\xe2\xe0e#P\x85\xe8얻\x89I\x92mJ/\"\xa5T\xac>ª\x96OR=\xcb\x15E\xf2f\xb1\x01IO\r\xbej\xf7\xf6bK\xf4GZ\xa1\xbe\xbe\xa6\xebT\xe3<]\xc1\xca$\xeb͢lȔ\x16\xcc\xd95\a]\x1e\xf9qv\x14S\xfdO4\xf6\a\xcd\x1f\x1c\xe68\x15϶\x89\xb7\xea8\x7f\xcf\a\xb0\a\xd0\r\x98yE\xb8혝nϣ\xdb8&\x00\xdcP\x7f\x1aW\xd8\x01/\a\x90\xb7x\xa0\x83^\xc0-*6\xaf\v\xeb\xe0Ǻ\x8e(Q\x12\xf0+\xee\x19\xa4 '\xe6\xf0\x12}\f`\xc0+4 @\xd5t\x12\x99\xa1\x93\xa5C\xfav\x0f\xe3\xfb\xc0\aJ\xf95#\xfd\xbb\xc3\x03\x130\r3H\x86i\xd0\xe4\x14\xbf\xceզ˱V\a}=\x8f\xa6\xfd\xb9\xd8g\xa1\xfcR\xf9u0\xea\x80\xf69\x18i2\x80\x83\x90\xe5Ɛ\x9d\x80\x05\\Č\v\xaeB\x9f\x0eD\x8a\xf7\x19\xadD\xd5\x106\x94j\xf6\xabͣۅa\xef\xd9A\xd5\x11H\xdd\x04wf\x00\x16\xe3\xb0\n\x7f\x88\x00\x96\x1f߯\xfb\xbfX\xe5A\x16\x94\xf9\x8a̎\x02\x956\x9b*d.\x8e\"\xafy\xd1[d\x1d\xb5h\xb5\x87)ͤ(b竨VM\xfb\x9e\x1a\xb1/\x95;gYl\x8e\xa6]\xc44,\xc6\xc5\b\x8c>\xc2bd\x93Zz\xe4\x90\x0e5M\xc7XL\x83\"\x96 +\x86\xb8\x89Q\xa2\xf3x\x8a\x14\xef~\x06;q\x01b\"\x11-\xf7\xe2\x03\x92\x14L\xc4EH\x88Y@Y\"\xfe\xa1\x8fl\x98&\xb9\x00\xf5\x90Ĝy\x84\xc3b\\\x83\xc7\x11L\xce#\x19\xcd\x10\xc1)L\x12\x1e\xc50L\xa1\x13\xa6Y\x1eA.\xa4c\x12&I\x13^a\x1e\x89\xf0zx\xc3\u05c8\x02\xc6M\xcd,\x9a\xe0EQB\x02^`\tJ`\x96c\x17\"\x02\u0089\xffH\xbfKq\x00\xfds\xfe\x11\xa2)\xa7\xff#\xa7\xfb#\x14'\xcf\xfcS\xcf\xf4Gh\xcfl\xbb\x93Z2\xf9㒳\xfc\x10\x86\xfcʫJ\xc8\xfd\xb9\x9e\xa4jӤ&\x9d\x01\x01\xba}\xf6T\xa9\x1b-\xf4\xe2\xacX\x97\xeeVn$&k\xd2zBZ\xb5f\xf7\xf2tF\x97\xae\x04Dc\x90\xfe\xb5-\x1cֳ(\x8a\xee\xdd$\"\xdb%\xe5o\xf9\x99xf\x00+\x8ey\xd8Q\x11*\xdd\xf3\x8e\xe7B\xb0/\x83\xea\xddDᴷ\x1ds\xb4\x85=\\\xe8m\x97uaE\x15]\xf2\x95VGAi\xc7\x03\x9c\x02?\xff\xa6\xe8V\xd0\xf6D\x94\xbe<\x86ո\x1e\x04\x0e<\xb6\x86\x9e\xa1(\x187\xe7\xd3\xcf\xdc\xc5\xd8L\xad\xe8\xae\x1bJ\xb2\xd1\a\x7f\x81\xf6\x96Vl,b\x97͕\xcd\x12\xc9\xd0\xe5Z\x13Ɉ\x8c\xeeE\xd3\xfe\xb0s\xdd\xe9\xdb\xef5\xe8\x13SG:\xd3\xf7\x0e\xd2\f\xec\xde\xd9\x15\x83\xf1[c鼹tױ\aqBk_ؽt;v\x94\xec`\x8cD\aM\\\x1b\x1b\xa15ǰg\xa4j\x94\xaaT\xa1u\\\x1f&7\xa6T\xcc\xfau#\xa5\xe5\xb1Ҭ\x97r\x95x\xe9\xf2\x88i\x82d*\x06=\xedLd\x16s~\xad\xc8i.vJv\x1a\xd30\xe5\xd7\xc0\x92/\xc0\x90/\x88\xa1\x96EQ\xc9lJ\xc1\x8a_%\x96\xbab4u\x8dx겈j\x86\xe4\x00\x03\x9e\x82\xeeN:\xc6K>\xb3I9e\x9b?9\x9eFm'\xa0\xb5\x13N\x83\xe6F\x9a\x80\xca^\x86\xc6N\xe0\xe1\x95b\xad+E[\u05c8\xb7\xae\x1bq\xcd\xc6\\\xb3\x9a3\xf3\xf32\x14\xf5Ň\f\xcdq\xf4g\x95Ã\xd2v.@x\x18֏\x1c\x01v\x82&U\xe4L6Uc'\r\xe8\xfb{\xbf\xff\xb2I\xc5O\xeb\x1a\xf7\xf7W\x95\xe3\xd8\xe6\xce\x16\x1e\a\xd5Ϯ\xd0\xee@\x83t\x0fK\xfc\xd7\xd7/\x9f\x03\xfd\x98?\xea\x9d\xde\xc1\x9b\x06\xce\xc1\xc8=s\xfc\xe9\x93\a\xdc8n\xd1\x1e\xfeʇ\x04\xbc\x12\xffIov\xcd'd\xee\x1f6T\xb5\xf1\x96譯p\xa0\x1f\xce\u07b6\x80\xbbG\xe0Ȩ\xf6ov=\x8a\x11\xd8i\xf8\x93ыI\xcd\xee%\xc60Y\x0e\x84\x84\xab\xeea\xe3F\xb7f\x9f\xd0u\x93'\xa6\x9c\xe2\x1d\x84\xceW\x15\xd7\xf6D\xdaan\xc3\x18Ɠ2\xcd\x1e2\x95:\x195\xb5\xe7oAEy\xdb<\tE\ap\xa7\xaa\x7f\x9a9\xe4\xe8%\xe3\x18\xbf=1{o\xe2\x15\xc71\xbe\x1d\xaf\x88S\x91\xcfQ\x04ī\xa5\xa4\xbc\x19z\xf8>g\xd6\x1eC\xc5i{\x86\x91l\x93։\xf0\aۓI3\x92W\xe6\x10\xc9\n\xbd̦\xd1CU\x96\xdb:q>\xaenoJ\";t\f\xd034&Jw\x9e\xed\x1b\x8c\tת#D\xdb0\xb9\xd0R\x14\xb7\x9d\xc0\xfc\x8f9\xf2L|\x16\xe4\xe2\aA\x1c{FL\x05e\x9aЌ5\xba\xd0\xf2\xe5\x82\xc3\xceY\x17.\x01\xd8:\xedw&\xbe(q\xf1[\x12\xf3̊0j\xec\x19\x89\x94\xa7\"\xfe\xae\xfc\x9c0I&;@^\x17\x90\xf0\xc0\xdb\xd7N\xd5\xf9'\xde\x1a±5\xa9\xfa\x8f\xbc!_;\xdb+:\xbc\xfd\xc7\xe4<\xd3=\xe5\x11\x88w\x97\xa4\xf3\xecݫS\x19\xfa\xf1\xa6\xce20fW\x17\rZ&\xd3\xc0-\xe4M\xf5(2\xbf\x99\xc3\x02XH|\x17Yu\x9eѻI\x90\x8c\x89\x98\xc9\t\x13\x99\xf1\xca\x12\n\x9e\xbc\x8cZk\x9a\xb2\xfbM\xedΞ\xfe\xeb\x91\x1d7Z\x1e\xce\xe8\xc18\xc6\xf22\xe2\x89\r/\x82\r[\xd0\x03\x9b:\xef\xc0w\xba/\xa4\x05TN,\xad\xcdM@T\xe6\xeb\x0emG\x86\x9c\x1f$\r9\x83#H\xa6$\xdd5\x81|\n\xbe\xfb\x8d\xd2f\xfa\b\xfa\xad\tt\bP\x84\xbe\xe2W˵\rC?\u05c8\x9d\xd2%\xb7w,\xe7\x16V\xd8\xfa\xb2\x1d2\xfez\xa1\xd6\xf3'\x1ctiŇ\xc1tӄ\xc4[\x14\xfe\xaaI\t\xc6\xf0}\xe3\xbe?\x83\x06\xb6\a\x89,\x9ez\xa0\xad\xbd\xad\xe3Wp\xc0\x9d!\xb7xfk\xee;p;e8\xfb\x89\x9d\x1b\xb8W?)\"؏\xae\x1b!-\xec\xcfN]\xfcM\xa1G\xe0f\xf8J\xec\x19#>u\xeb\xfa\x9c\x99\xe3\x81{\x92\x84;\x90\x18=*jE\x88RF\xac\x11\xf6\xbc\b\xfaU\x1d\xb8\x993\x97\x0fX'\\\xa1\xeb,\xca`)\x1fG\xc6\x14\xbfҳb\x9f\xe19\xf2\xf5\x13)=\xe5A\xe3Ki\xc56\xf2A\xab\xbd\x06s\xae\xd2+\xba\xe3!\xe4\xfe\x93\xd2\x0fE\xbd\x172@\xf0\x96U~\xe0\xda\n^\x14'7\x9eH\xdb\x0f\xcdb\x8e\xfc6\xdfz\xe4\x87)!\xf99\xcf&\x05\\\xb56\xa7\"\xa4[\xe8t\x81m\xabj\xdb]\x15oM\xbb`b\x01\xb4\xa7\xb6f\x9f\x95\x85&W/\xfaD\x05\x06\xcfƮ`\xb7Sں\x1c\xcej\xc5\xc4\xce\x1b\xeaX\xae\x81\x8b\x82|\r\xf7\xc6-: \x01]\x12v>\x1fOjZ\x15䤔\xfc\xe4\xc2R\x9ee5ځw\xc6\xf2؆\xf6\"ז\x9c\x1b\xaf\xcd)\x11\xe5\xa6[?\x84tu\xb9\x05M\x97:\xf0g\xc7:\xba[\xe7LP\xf4\x9c\x92\xd1=\xae\xce\xd5^fp9\xc7\xd3jSƇ~W\x96\x17\x9bqG\xad\x7f!!T\x0e\xb11~9\x9fF\xef5\xcfq,\xa20MS\x94Yv\xe0r\x8f\xea\xa3U\xbd?4*8f\xa9\xc7Ҩ5\xe5|*Z\xa9\xa69\U000f2d56\x9d\x94\xad?\x05\xcb\xdb\xe1N\x11\x9dfᄟ\xa9[Dnk3\xee\xdd]\xad\x98\xceļ\x9d\x91\xc6#\xfc\x8f%\x94B\x13nN2\x9b\x86\t\xbb䑘\xb8\r4Ō\xe8|\x83\x05\xbcd\xbe\xa1q\xfa|[\xaf\xb78\xb5\xbeԒɏ\xfbٯ\xc0\x0eg\xd2/\xe1\x85k9\xb6\xf0h~\x91\x91/\x12\xb7\xcf6\x80D\a\x93\xc0 \xd1\xfb\x96\xe4t,\xe3\x85\xe9y\x99sAW\xaf\xf2˼i\xea\x18}\xe9\x9f\xd7\v>\x067\xe6c\x8a?\xfc}P}p\xe7\x02=㖢\xf7a#\xcc\xf9g\xb1k\xfe-¶\x80\x7f9\xab\xf1\aߝx\xe6Z\n\xb9\x9f\x9b\xfco\xbeZ$\x1c\xf0\x14\"\x01Ad\x12!DX\x14\x104\x83\x1cy\xf9;\x04\t/\b\t\xa2\xdb\xc9\xd9GR\xe4\xbc\xc3dߓ\xff\xf2\x7f\x01\x00\x00\xff\xffT\xf5\x7f\x80\xacd\x00\x00"), - []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xec=Mw$)rw\xfd\n\x9e|\x18\xdbOU=m_\xfctk\xab{\xecz;ӭ\xd7\xd2\xf6\xc9\x17*3J\xc5(\x13r\x81,uy\xdf\xfew\xbf\b \xbf*\xc9$K\x92gfW\\\xba\x95\x05A\x10\x11\xc4\a\x04\xb0Z\xad.x%\xbe\x816B\xc9k\xc6+\x01\xdf-H\xfcˬ\x1f\xffì\x85zwx\x7f\xf1(d~\xcdnjcU\xf9\x15\x8c\xaau\x06\x1fa'\xa4\xb0Bɋ\x12,Ϲ\xe5\xd7\x17\x8cq)\x95\xe5\xf8\xd9\xe0\x9f\x8ceJZ\xad\x8a\x02\xf4\xea\x01\xe4\xfa\xb1\xde¶\x16E\x0e\x9a\x80\x87\xae\x0f?\xae\xdf\xff\xdb\xfa\xc7\v\xc6$/ᚙl\x0fy]\x80Y\x1f\xa0\x00\xad\xd6B]\x98\n2\x04\xfa\xa0U]]\xb3\xf6\a\xd7\xc8w落\xf3\xed\xe9S!\x8c\xfdS\xef\xf3\xcf\xc2X\xfa\xa9*j͋N\x7f\xf4\xd5\b\xf9P\x17\\\xb7\xdf/\x183\x99\xaa\xe0\x9a}Ʈ*\x9eA~\xc1\x98ǟ\xba^1\x9e\xe7D\x11^\xdcj!-\xe8\x1bU\xd4e\xa0Ċ\xe5`2-*K#\xbe\xb3\xdcֆ\xa9\x1d\xb3{\xe8\xf6\x83\xe5W\xa3\xe4-\xb7\xfbk\xb66To]\xed\xb9\t\xbf:\x129\x00\xfe\x93=\"n\xc6j!\x1f\xc6z\xfb\xc0n\xb4\x92\f\xbeW\x1a\f\xa2\xccrb\xa0|`O{\x90\xcc*\xa6kI\xa8\xfc'\xcf\x1e\xebj\x04\x91\n\xb2\xf5\x00O\x8fI\xff\xe3\x1c.\xf7{`\x057\x96YQ\x02\xe3\xbeC\xf6\xc4\r\xe1\xb0S\x9aٽ0\xf34A =l\x1d:?\x0f?;\x84rn\xc1\xa3\xd3\x01\x15\x84w\x9di \xb9\xbd\x17%\x18\xcb\xcb>\xcc\x0f\x0f\x90\x00\x8cHT\xf1ڐp\xb4\xado\xbb\x9f\x1c\x80\xadR\x05py\xd1V:\xbcw\xb2\x97\xed\xa1\xe4\u05fe\xb2\xaa@~\xb8\xdd|\xfb\xf7\xbb\xdeg6\x90%O)&\f\xe3\xec\x1bM\f\xa6\xfdLev\xcf-Ӏ\x9c\ai\xb1F\xa5a\x15\xa8\x9b7 \x19S\x9aU\xa0\x85\xcaE\x16\xb8B\x8d\xcd^\xd5Eζ\x80\fZ7\r*\xad*\xd0V\x84\xa9\xe7JG\xa3t\xbe\x0e0\xfe\x01\a\xe5j9I\x04C\xc2\xe7'\x14\xe4\x9e\x0en~\b\xd3\xe2OL\xea\x01fX\x89K\xa6\xb6\xbfBf\xd7\xec\x0e4\x82\tXgJ\x1e@#\x052\xf5 \xc5\xff6\xb0\rJ\xbd%a\xb4\xe0\xf5A[h\x02K^\xb0\x03/j\xb8b\\\xe6\xac\xe4G\xa6\x01{a\xb5\xec\xc0\xa3*f\xcd~Q\x1a\x98\x90;u\xcd\xf6\xd6V\xe6\xfaݻ\aa\x83&\xcdTY\xd6R\xd8\xe3;R\x8ab[[\xa5ͻ\x1c\x0eP\xbc3\xe2a\xc5u\xb6\x17\x162[kx\xc7+\xb1\"\xd4%i\xd3u\x99\xffS\xe0\xa8\xf9\xa1\x87\xeb\xc9|s\x85\x14\xe1\x04\aP#:\x81qM\xdd(ZB\xe3'\xa4\xce\xd7Ow\xf7]a\x12fH}\xa2{G\xc2Z\x16 \xc1\x84܁\x9f\xd1;\xadJ\x82\t2\xaf\x94\x90\x96\xfe\xc8\n\x01rH~SoKa\x91\xef\x7f\xa9\xc1X\xe4՚ݐyA9\xac+\x9c\x81\xf9\x9am$\xbb\xe1%\x147\xdc\xc0\xab3\x00)mVH\xd84\x16t-㰲\xa3Z\xe7\x87`\xde\"\xfc\ns\xfc\xae\x82\xac7e\xb0\x9d؉\x8c&\x06i\xcfF\x05\f4\xa8+㳖~!55\xfc:\xc0\xc3\xe9\xb2\xd0+\x18\xb4\x1fvO\x1cn\xcd\x18ʕ\x83\x86:E\xaa!wǴ`\x87\x12\x1e\xca\f&}\xad\x97j\xdfN`2\xaf\xea\xd6\x11\x1cO\xb8J?AY\xa1ژA\xf1\xdeWC\x14\x91>y\xe35\x05\xc3\x1fԬ\xf2ڕ\x9d(7\xean\x0fȷ\x83Ƚ\xf6:\xe1*\x9b\xe4,\x96̈;\xc9+\xb3W\x16m\x9c\xaa\xedX\xad\xc1\x00n\xee6\x83F\x1d\xce#VdÉ\xd1V\xb1'.N9\xed\n\xca\xe5\xcd݆}C\x97\b\x02L\xe6,9\xb3\xb5\x96\xa4\x8e\xbf\x02Ϗ\xf7\xea\xcf\x06X^\x93V\nv\xf9*\x02x\v;\x9c\xf4\x1a\x10\x066\x00\xadq\x0e\x18BM\xd5vM\x0eG\x0e;^\x17\xd6+9a\xd8\xfb\x1fY)dm\xe1\x94\xefl\x9a\xf7D$ny\xa9\x0e\xa0\x13h\xf8\x91[\xfe\v\xd6\x1d\x90\x0ea0\x02\xe2\xd9Od\xdc\x1e#\x03\xc5&['\xa9l\xb3\xeb@\x15\x86]^\xe2<\xbbt.\xf1啫[\x8b®\x84\xa4~\"0]\xefO\xa2(B\xff\xe7Q\xc3\x11\xd7\xf1\xd6ܫ\x9f\x8c\x13\xeb\x14\xe2D\x9a\x8e(\x98J\xe5\xec@\xf5b2&\n`\xe6h,\x94\x9eR\x1dυ\x88Kڱ(<\x18öǀ\xfb\xf8\xb8e]\x14|[\xc05\xb3\xba\x1e\xefvJ\x91\x8d\xd1\xe6+\x18+\xb2\x04\xca\\\x0eI\xe3Z\x8e\x10F\xd3\x0f\x11\xa2\f(\x80.\x0f\x7fD\xb7\xdbS\b}\xa7\xa2\xe8\x10w\x9e*\x8c\xfd\x8fd\x1f\xd1\xdcgh\x84\xaf\xbdq\x17P\x90C!\x15+\x94|\x00\xedzD\xc7)H\x98\x06\x94\xb8<\x02\x15-\xad\x86\x02]\x06\xb6\xab\xd1\b\xaf\x19j\x82\xa8\x8c\bi,\xf0|}\xf9Z̃\xefYQ\xe7\x90\xdf\x14\xb5\xb1\xa0\xef0\x04\xccC\b<\xaae\aL\xfc4\t\xc0\xbb_\x85\xc8\x00\xf9\x90\xb9J+\x8a4cDj=\xb1c\x05.\xf0E\xa6zL[\x17\xab\xa3*\fX\xacr\xf9\xaf\x971%\x8a\x12\xd0\xef\xbdߏa\\CC\x8d\x9eF\x8d@l\xf4,\x94\x95=\x8eˑ\xb0PF\x888\xabr\x16\xb0\x97k\xcdǔj\x18N\x13џ\xcf\xde\x18\x88\x01\x83e\xa8\xf6\x1b\xb1x\xd8\xff?\"\x93\xcfb\xab\xa1u,.$\xb2\xb3\x10\xc6\xf6\xb89\f\x88\x1a\xcc0vF\x9ab\xd0\"\xa4\x83\x89ʭü\xdf3\xcdΙ\t1\xd1o$͋\xf3\x9eDŽ\xea\x0fH\xb0\xbdR\x8f)D\xfao\xac\xd7\x06\xca,\xa3%U\xb6\x85=?\b\xa5\xcdp\xb5\x05\xbeCVۨ\x9e\xe0\x96\xe5b\xb7\x03\x8d\xb0h\x81\xb0YO\x9c\"\xd6t\x98\xc0:\n(Za0\xae\x96\xe9\xc8<\xa2Fl(\x14\x8eE\xa12B\x1c\xbdx\xb2\xee\xb98\x88\xbc\xe6\x05\x19z.37>\xde\xe0\x17sOf\x04\xe2\x04\x7f\xe7N\x84Q \x97zQ\xb6\x92\x80\xeeu\xa9t\xcc\xf3t\xe5\x14L\x9c\f[N\xc1q,$m\x8b\xae\v0\x1e\x15\xe7\xc0\xb6z\xe7\xaa\xe5\x94[\xa0*\xf8\x16\nf\xa0\x80\xcc*\x1d'O\x8a\x10\xb8\x92\xaa?#\x94\x1dѤ\xfd hV\x89\xb6\x05\x03̽\xc8\xf6\xce\xddD)#X,W`Hc\xf0\xaa*\"V\xa8-\xb3\x92\xe1;\x9bS\x1amIP\x1fC\xb81EҖD\x1dܖ\x19mܧz#6oD\xef\xa1)\x9f%웓\xe6//\xecHn\x01\x86\x9c>\U000bab98\xb0\xe1k\nԞ\x1fh\xfe\xce\x18w\xdel\xd9\f[\xbf\xf8ly\x11\xae5h\xfc\x9d0\x8d\x8c՝\xb7U\x8b\x18\xf6s\xb7\xe5\x15\x13\xbb\x86a\xf9\x15ۉ\xc2\x02\xf9Rs\x88v\x1c\x9dYν$\x81Rm/\x96\x92\xdbl\xff\xa9Y\xd6Nh1\xa0\xd5\x10\x80\xf3\xcbC\fC\f<\x9d.\n4\xc0$\x90\x9dA\x91\x9b\xd6\xc4xn?\xef\x8aq\xf6\bG\xe7Y\x8d.\x0f\x8d\x15d-o@j\xa0\xcdER#\x8fp$P~\xb70\t\xde\x12Qq\xe5\x11\x8e\xa9U\aDE\xfc\xfc>\x85\xa3.~\xa0Q\xa4L\xa5\xb64D\xf5s\x87Y\x956X\xb6L)\x85\x12(~\xe6\xb0\x1b\x86\xf5\xb6\xc8\x1f\xe1\xf8\x83q\xec\xc3Y\xb3\x17\xd5\x02\n\xa0¦%\x19\xb5k\xf6\x86\xbf\xf1B\xe4Mg4O\x16@\xdc\xc8+\xf6YY\xfc\xe7\xd3wa\x10E\x99\xb3\x8f\n\xccge\xe9˫\x92\xd8\r\xe2L\x02\xbb\xc64-\xa53\vH\x97E\xfd\xb78\x90\tE\x11m\xd8&\f\xdbH\x8c\xcf\x1c}\x96\xb0i\x0f\x019\x87VY\x1b\xda]\x96J\xaeܒ\x96\xefm\x01\xd0.^\x9eUJ\xf78u\xb5\x10\xe2(\x8a\x1e\xbd{\xb4V\ue5d3}\xf9\xa9\xa2\xa1*x\x06y\xd8e\xa3$\x00n\xe1Ad\xac\x04\xfd\x00\xacB\xbb\x91.T\v4\xb9+gHa\xbak\x11\x8a7\v#{\xdace\x85\xb3>\xb1f`sR\xf5Ȏ\xfft\xf5\xb4Q\x92y'\x7f(\x89\xfa\xdd\x14\xb5e\x96e!\xbfN}\x10\x87\xa4s?JN\x1bO\x7fE\xf3J\xe2\xfd\xb74kȅ6k\xf6\x81\x12\xf4\n\xe8\xb6\x0f\xab\x84\x9d\xae\x92@\"&\xc20\x94\x93\x03/\xd0}@\xe5-\x19\x14ΙP\xbb\x13\x0f*M\xc5<\xed\x95q6\xbf\xd9\x18\xbb|\x84\xa3ߜ\xedj\x89ˍ\x8c\xae\xda\xf7\v\xea\xfc\x13\xa5\xd5x-J\x16GvI\xbf]\x92c\xb6d\x8a\x9c\xe1\xbc-\x90\xea\x05U\xbf\xaf\x1e\xeb-h\t\x16̪\xe4\xd5\xca\xcf\x06\xab\xca\xe8\x1e\xa7+\x94F\xb7$\x8c\xc08=x<ظI6C\xf7\x7f\x8e\x02\xc9\xf3\xa1R&\x92i\x11A\xebV\x19\xeb\x16\x0f{\xae\xfa\xc8\xeabJ\xe4\xe8W\x1c\x19\xdfY\xd0\xccX\xa5Cb\x17\xaa\xec\xc1\xe2:J\x8d\x99\x97\x1b\xb7O\xe4W2\x1d`\fP/[\xed\xe2\xec\xc1\xa5۫\xc2\xff\xcf\xc3\xcc\xc8\xd1\"ؕV\x19\x98h6B[\x12\xad\xce\xccbo\xb3\xd0\xcb]\xe0\xb7KR\xeb)\xcbС,s㑴g\x04E\x9f\xbew֬Q\x85\xe1\xdf)\xa2|\x0e\x8e\x8cr\xbb˒\x0f\x93\f\x93ѽq\xad\xc3\x04\xf4\xc0\\\xb0\xa5\x1fjRH\xcb|n/\x92\xbf7\xa7\xa5\x14rC\x1d\xb1\xf7\xaf\xe6\xe8\xb0`\x06b\x19Ice\xc0\x0e߾eH\xf3!5\xf6e!UM\xd1>\x8f\x86\x1egOwA\xd29\xc5\xd0\x11\x97\xcav\x17z|O?\x18\xb6\x13\xda\xd8\x16\xe1\x05P\x85\x99\xc8z\x1a\x1d\xde\x19\xf1\xa9\xfc\xa4\xf5\xd9\xe1\xe9\x17\u05fa\xb3$\xb9WO>\xc1sIP\x1e\x88\xbf\xe7\a`bDŽe 3UKZ,Cu\x81\xdd,\x80\xe8\x98\xe8\x8cI\xa2\xcd\xec4\x96u\x99N\x90\x15I\xa7\x90\xb3+k\xdd&?q\x91\xb6\xb2\xc5\xcec\xab\x9dJ\xa2\x1c+\xfd\xccP\x9fM\xd9\xcd\xe4-\xf9wQ\xd6%\xe3%\xb2eI̹sy\x98!\xed\xd7\xf1\xfa\x89\v\xebOS\xb8M\xd9e\xda4SeU\x80\x85\x90a\x99)iD\x0e\x8d\xfb\xe0\xf9?\x9a\xaf\x1a+\x9c\xed\xb8(j\xbd@G/\xe6\xccҘϫ\xa7\x97\x0f\xe4\xd2\x11Y\x111\x13\x17\xec\x178\xdc\xf3\xf6\xa3\xd2\xcb\\\xe6[\r/\xef\x9aVZ(ʁ\x9d\xf1Nga\x92\xf7\xda\xf7N\xbd\xf0ry\x8c\xb9\xa7\xb3P\t\x937\xf7\xb4)o\xee\xe9\x9b{\xfa\xe6\x9e\x0eʛ{\xfa枾\xb9\xa7\xe3\xe5\xcd=\xed\x947\xf74\xd9~\xa4`\xb8\xa2\x95ۉ\nIX%\xa6o̡=ӗ\xcfR\xf2gA\x96dWo\xc6[\x8e\x9c\x05Zt\x86\xc4t\x8c^\x93n\x8dS2L&w\xa64\xc1\v\x7f\x81\xb36\x01\x81\xb3\xcf\xdal&\x01\xbc\xe0Y\x1b\x8f\xe9p\xed\xfc\x05O\xda\x04Z,?\x84q\xe5ӘJ\xe0aK\xc8\xe5\xa0\xe4\xb1nc^l\x0f\x8f\xd1:\xbfq\xd6\xfdI\xb6\xe6\xf9\"\xf3\xffr~'\"6'\xa7S#P\x85A\xb9\xfacp\xe2,\xdaG\xa9\xed\xfe\x17\x1b]KX\xa7x\xdd5\x03\xddT\xcb~\xca\xeb\x1fG\xb0ϑ\xe4\xd4\xf371\xe7<\xae\xdb:\xc4Խ\xf3\x1e\xbfoZZ(\xbfTޒ\xa5\x9f{ߌ4{\xc6\xc9wn\x8e2\xdbk%Um\xfc\n\x0f\xf6\xf0!sW\x01\x84\x8e\xcc\x12e\xf0\x9e\xedU\x1d9\xe31Cׄ\xcc\xdbx\xbe\xad\xcf\xe0\x00\xcb\x0f\xef\xd7\xfd_\xac\xf2ٷ\x11\xac\x9f\x84ݻ\xfb\x18x\x9e\xa3\xa3\xde9\xe2\x13&\xaf\xbf\x93e(x\x11\x88J3)\n'\x95\x01B߀~\xa9ܒ\xdf\xd9~\xcb\xfc\xc2Sz\x8e\xee\xd2\xcc\xdc&\x97r\xdeK~F>\xee\xb2\xc3R\xb3\xb9\xb7)H\xb3\x94\x8c\xdb\xf1\\\xda\x19\xa8K\xf2lS\xd7\x14\x13rj\xd33i\xd3\xc8\xc3\xe8&\xa5\xd4\xfc\xd9\xe4(45W\xf6u2d\x13\xf3b;ٮ\xb3 \xcf̆M&XZ\xe6kr\xbek'\x8bu\x9eZ\x13Y\xae㹫\xb3 \xc7r[S2V\x93pM\xceSm\xb2O\xe7wF\x9e\x95\x9d\xfa\xf2\xe7`^r\xddb:\xd74)\xc34imc\x1e\xe7\xa4\x1cҥ\x99\xa3IT]\x9a%\xdad\x80Nt\x9c\x94\x1bz\x9a\xf795\x94ٌ\xd0x\xb6\xe7\x14ر<Є\x1c\xcf\t\x90\xdd\xec\xcf\xc5n\xc0\xac4\xcdVX\x9a\xbb9~?Z(\xf3ֹ\xf8-d\xf6\xb9dR\xba\xe74\xa7\x04w_\x06MPZ\x82\x9f8\xe6\x88\xc7Ce瞟\xe1\x88G@nv\xac\xac\v+\xaa\xa2sA\x99\xddñ\xb9\xf2\xe7WE\a\u05f7G\x82\xf6\xe5k#\xf21\x90\xfd\x90\x82\x1b\xf6\x04E\x81\xff\x9eP!s\xd7\x01fj\x05h\xa5\xe2\x1b\x81\xfe\xaa#\x7f\x97\xe0\x95[\x16\xa3S\xfdd\x01K\x844}\x01֤)\x99v\x8f\x9dWO\xdf\xfeR\x83>2\xbas+\xf8AQ1kO{\xfa\xc9l0&\f\xca\xc7k1w)e_\x19\xc5gC\xa3\x02\xd8\a\xe9\f\xf3\x10W\x82\x85Z\xa7\r\xa7\xa6\x94-FO1\x10R5\x10\"\xedS\xbc\xef%\xc7\x1f_#\xb8z\x89\xf0*\xc9\x11y\x8d\x10뵂\xac\xa5a֒䍤㋯\x11l-\t\xb7\x16\xf9\x8c\xe9\xc7\x13_\xebX\xe2+\x84]g\a^\x8bH\x97z\xecpq\xf8\x950\xbe\x99c\x86'>Z\x02\xc8\xe8\xf1\xc2\xf1\x10,\x01\xe2ɱ\xc2\xd9 ,e\x1e\fôg\x1f\x12LNdZ\xb4\x9b\x9e\x9a\x84\x94\xb6\xd1=\x7f\xf8/\xf1\xd0_\xe26x\n\xf6\x89\x87\xfb\x96\x1f\xeaK\xa4\xf3\x99\xe1\xd9d\u05c9\x87\xf7\x16\x05hg\x86h\x93\x10\xa7\x0e\xebM\ai\xd3\vp\xc3Czg\xb8\x13\t\x12\x96Pe\xf9A\xbbgo\xc6(\x9d\x83\x9e\xdd\xd7Z\"γ\x82<\x88\xa3\xfa\xfd\x0fvt\u008d\xa8X\xab\xbbg\x16\xe3\xa8j\xee\x1d\xc9؟\x84\xf4\xbb\xf5(\xb8\x1d\x9f\xa4\xb7\xf1\xd6:L\xf1}\x9d\xd6K\xf5\x17\xab\xbb\x1d;\x03\x15״\x8f\xbf=\xba\xa4 \xb3f\x9fx\xb6oz\x88\x80\xa4~\xf7ܰ\x9d\xd2%\xb7\xec\xb2\xd9\n}\xe7:\xc0\xbf/\u05cc\xfd\xa4\x9a\xf4\x91νb\x11\xa8F\x94UqĈ\x89]v\xc1ti^\xd6ɂ\x88\xc5(\xd8\\\xf8\v\v\a\x97\n\xefTQ\xa8\xa73\x97.x%\xfe\x8b\xde1I[\x1b\xfbp\xbb\xa1\xeaA\xaa\xe8\r\x94&{\xae\x91\xb1-L+\xf4v\xe0\xe4zt\xa1\x8ed\xaf6\x7fN@\xa4W\x04\x82\x9f\xe1\xd5x\xa6P\x8b\xddn\x1c\x96k\x12,.\x8fL\xf9{\xe2\x85\xceW\x15\xd7\xd1M=\xe6\xe5\xc1\\\xf50\fv|n\x05kҬ\x9d\xbe\x8a\xd0-=\x9a\x87\a\x12h\xb3\xf7X\xf5\xb7щ\xd2\x1dz>\a\xa7\xe9\x83˳G\x96_\x01\xa7i\x97iET\x8c\xfc\x14M\xc7{\xf1\xd5C\xe3/\x91\xffE\x1d\xe0ct\x15\xb1\xffd\xc0\xa0\xc9H\x02]\x80:umz\x9b5\x17\xbf\xce\xfa\x052\xe2\x02*\xfe\xe2\xeb\x05\xe3\xf3-\xc6^i\xf0\xf7\x7f\a\xd8\x13\xb6\r\xa7\xec\xed7\n7\x1bu\xe9g\xb8\x0f&\xc3R\xe1\xe0\xaa\xd6\b\xc8\xd83\v/E-\xab4\x7f\x80\x9f\x95{\t#\x85Z\xfd\x16\xbd\xc7P\xbc3\x17\xb2\x89\xfd\\\x8b)s?\xb6!\xc0\xf6\x90\xc1\xc9u\xf4\x88홷\xed[[$\f\xee\xfe\xfeg7 +JX\x7f\xac]\x86\t\xea]\x03H\xe90P\xd7h\x1b\xd7N{\xf5D\xf7\xb9w\x9f\xab\xe8<\b\x04t\xa8\x81\xd2F\xcf\x1a͡\xf7 D ]\x8a\xb0\x7f\x1bo\xd9\xf1\xa1:L\x9cJ!S\xbb(,n\x8c\xca\x04\xb9]\xb4fNg\t^\xef&\xe2)\xf7yB\x7f\xd6\x06\xbe{\xd6.\x87\xce>\xb26¿\xe6Y\x9d\xe8;3.\x90p\x8f\xa0\xad\x10\xfey\xec\x1c\x9d\at\x8d\xf5\xdc\x13DX\xa79\a\xe6\tM\r\xc3\xf5\xd7w1\xd4\xc7\x0f\xf6\xac\xd8g8u\xe4W\xec\x93\xc4A\x9c\xdawwz\arZD\x1d{\x90lr\x88\x87\xa6\x15\x1d\x9d\x1a\xd1\x16}57\xa8>H\xec\xa4\xe7L\x9a*\xee\x98\xd4\x18[\xffY\xec\xdc\nw\x86c\xfa\x97\x93\x1aQ\xc55\xa9\xb4b\nktJ\x9d|4\xa0\x0f\xf4~H\x10\x12oû_\xeam{\x1b9\xfb\xeb\xdf.\xfe/\x00\x00\xff\xff\x80\xea<õr\x00\x00"), + []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xec=Mw$)rw\xfd\n\x9e|\x18\xdbOU=m_\xfctk\xab{\xecz;ӭ\xd7\xd2\xf6\xc9\x17*3J\xc5(\x13r\x81,uy\xdf\xfew\xbf\b \xbf*\xc9$K\x92gfW\\\xba\x95\x05A\x10\x11\xc4\a\x04\xb0Z\xad.x%\xbe\x816B\xc9k\xc6+\x01\xdf-H\xfcˬ\x1f\xffì\x85zwx\x7f\xf1(d~\xcdnjcU\xf9\x15\x8c\xaau\x06\x1fa'\xa4\xb0Bɋ\x12,Ϲ\xe5\xd7\x17\x8cq)\x95\xe5\xf8\xd9\xe0\x9f\x8ceJZ\xad\x8a\x02\xf4\xea\x01\xe4\xfa\xb1\xde¶\x16E\x0e\x9a\x80\x87\xae\x0f?\xae\xdf\xff\xdb\xfa\xc7\v\xc6$/ᚙl\x0fy]\x80Y\x1f\xa0\x00\xad\xd6B]\x98\n2\x04\xfa\xa0U]]\xb3\xf6\a\xd7\xc8w落\xf3\xed\xe9S!\x8c\xfdS\xef\xf3\xcf\xc2X\xfa\xa9*j͋N\x7f\xf4\xd5\b\xf9P\x17\\\xb7\xdf/\x183\x99\xaa\xe0\x9a}Ʈ*\x9eA~\xc1\x98ǟ\xba^1\x9e\xe7D\x11^\xdcj!-\xe8\x1bU\xd4e\xa0Ċ\xe5`2-*K#\xbe\xb3\xdcֆ\xa9\x1d\xb3{\xe8\xf6\x83\xe5W\xa3\xe4-\xb7\xfbk\xb66To]\xed\xb9\t\xbf:\x129\x00\xfe\x93=\"n\xc6j!\x1f\xc6z\xfb\xc0n\xb4\x92\f\xbeW\x1a\f\xa2\xccrb\xa0|`O{\x90\xcc*\xa6kI\xa8\xfc'\xcf\x1e\xebj\x04\x91\n\xb2\xf5\x00O\x8fI\xff\xe3\x1c.\xf7{`\x057\x96YQ\x02\xe3\xbeC\xf6\xc4\r\xe1\xb0S\x9aٽ0\xf34A =l\x1d:?\x0f?;\x84rn\xc1\xa3\xd3\x01\x15\x84w\x9di \xb9\xbd\x17%\x18\xcb\xcb>\xcc\x0f\x0f\x90\x00\x8cHT\xf1ڐp\xb4\xado\xbb\x9f\x1c\x80\xadR\x05py\xd1V:\xbcw\xb2\x97\xed\xa1\xe4\u05fe\xb2\xaa@~\xb8\xdd|\xfb\xf7\xbb\xdeg6\x90%O)&\f\xe3\xec\x1bM\f\xa6\xfdLev\xcf-Ӏ\x9c\ai\xb1F\xa5a\x15\xa8\x9b7 \x19S\x9aU\xa0\x85\xcaE\x16\xb8B\x8d\xcd^\xd5Eζ\x80\fZ7\r*\xad*\xd0V\x84\xa9\xe7JG\xa3t\xbe\x0e0\xfe\x01\a\xe5j9I\x04C\xc2\xe7'\x14\xe4\x9e\x0en~\b\xd3\xe2OL\xea\x01fX\x89K\xa6\xb6\xbfBf\xd7\xec\x0e4\x82\tXgJ\x1e@#\x052\xf5 \xc5\xff6\xb0\rJ\xbd%a\xb4\xe0\xf5A[h\x02K^\xb0\x03/j\xb8b\\\xe6\xac\xe4G\xa6\x01{a\xb5\xec\xc0\xa3*f\xcd~Q\x1a\x98\x90;u\xcd\xf6\xd6V\xe6\xfaݻ\aa\x83&\xcdTY\xd6R\xd8\xe3;R\x8ab[[\xa5ͻ\x1c\x0eP\xbc3\xe2a\xc5u\xb6\x17\x162[kx\xc7+\xb1\"\xd4%i\xd3u\x99\xffS\xe0\xa8\xf9\xa1\x87\xeb\xc9|s\x85\x14\xe1\x04\aP#:\x81qM\xdd(ZB\xe3'\xa4\xce\xd7Ow\xf7]a\x12fH}\xa2{G\xc2Z\x16 \xc1\x84܁\x9f\xd1;\xadJ\x82\t2\xaf\x94\x90\x96\xfe\xc8\n\x01rH~SoKa\x91\xef\x7f\xa9\xc1X\xe4՚ݐyA9\xac+\x9c\x81\xf9\x9am$\xbb\xe1%\x147\xdc\xc0\xab3\x00)mVH\xd84\x16t-㰲\xa3Z\xe7\x87`\xde\"\xfc\ns\xfc\xae\x82\xac7e\xb0\x9d؉\x8c&\x06i\xcfF\x05\f4\xa8+㳖~!55\xfc:\xc0\xc3\xe9\xb2\xd0+\x18\xb4\x1fvO\x1cn\xcd\x18ʕ\x83\x86:E\xaa!wǴ`\x87\x12\x1e\xca\f&}\xad\x97j\xdfN`2\xaf\xea\xd6\x11\x1cO\xb8J?AY\xa1ژA\xf1\xdeWC\x14\x91>y\xe35\x05\xc3\x1fԬ\xf2ڕ\x9d(7\xean\x0fȷ\x83Ƚ\xf6:\xe1*\x9b\xe4,\x96̈;\xc9+\xb3W\x16m\x9c\xaa\xedX\xad\xc1\x00n\xee6\x83F\x1d\xce#VdÉ\xd1V\xb1'.N9\xed\n\xca\xe5\xcd݆}C\x97\b\x02L\xe6,9\xb3\xb5\x96\xa4\x8e\xbf\x02Ϗ\xf7\xea\xcf\x06X^\x93V\nv\xf9*\x02x\v;\x9c\xf4\x1a\x10\x066\x00\xadq\x0e\x18BM\xd5vM\x0eG\x0e;^\x17\xd6+9a\xd8\xfb\x1fY)dm\xe1\x94\xefl\x9a\xf7D$ny\xa9\x0e\xa0\x13h\xf8\x91[\xfe\v\xd6\x1d\x90\x0ea0\x02\xe2\xd9Od\xdc\x1e#\x03\xc5&['\xa9l\xb3\xeb@\x15\x86]^\xe2<\xbbt.\xf1啫[\x8b®\x84\xa4~\"0]\xefO\xa2(B\xff\xe7Q\xc3\x11\xd7\xf1\xd6ܫ\x9f\x8c\x13\xeb\x14\xe2D\x9a\x8e(\x98J\xe5\xec@\xf5b2&\n`\xe6h,\x94\x9eR\x1dυ\x88Kڱ(<\x18öǀ\xfb\xf8\xb8e]\x14|[\xc05\xb3\xba\x1e\xefvJ\x91\x8d\xd1\xe6+\x18+\xb2\x04\xca\\\x0eI\xe3Z\x8e\x10F\xd3\x0f\x11\xa2\f(\x80.\x0f\x7fD\xb7\xdbS\b}\xa7\xa2\xe8\x10w\x9e*\x8c\xfd\x8fd\x1f\xd1\xdcgh\x84\xaf\xbdq\x17P\x90C!\x15+\x94|\x00\xedzD\xc7)H\x98\x06\x94\xb8<\x02\x15-\xad\x86\x02]\x06\xb6\xab\xd1\b\xaf\x19j\x82\xa8\x8c\bi,\xf0|}\xf9Z̃\xefYQ\xe7\x90\xdf\x14\xb5\xb1\xa0\xef0\x04\xccC\b<\xaae\aL\xfc4\t\xc0\xbb_\x85\xc8\x00\xf9\x90\xb9J+\x8a4cDj=\xb1c\x05.\xf0E\xa6zL[\x17\xab\xa3*\fX\xacr\xf9\xaf\x971%\x8a\x12\xd0\xef\xbdߏa\\CC\x8d\x9eF\x8d@l\xf4,\x94\x95=\x8eˑ\xb0PF\x888\xabr\x16\xb0\x97k\xcdǔj\x18N\x13џ\xcf\xde\x18\x88\x01\x83e\xa8\xf6\x1b\xb1x\xd8\xff?\"\x93\xcfb\xab\xa1u,.$\xb2\xb3\x10\xc6\xf6\xb89\f\x88\x1a\xcc0vF\x9ab\xd0\"\xa4\x83\x89ʭü\xdf3\xcdΙ\t1\xd1o$͋\xf3\x9eDŽ\xea\x0fH\xb0\xbdR\x8f)D\xfao\xac\xd7\x06\xca,\xa3%U\xb6\x85=?\b\xa5\xcdp\xb5\x05\xbeCVۨ\x9e\xe0\x96\xe5b\xb7\x03\x8d\xb0h\x81\xb0YO\x9c\"\xd6t\x98\xc0:\n(Za0\xae\x96\xe9\xc8<\xa2Fl(\x14\x8eE\xa12B\x1c\xbdx\xb2\xee\xb98\x88\xbc\xe6\x05\x19z.37>\xde\xe0\x17sOf\x04\xe2\x04\x7f\xe7N\x84Q \x97zQ\xb6\x92\x80\xeeu\xa9t\xcc\xf3t\xe5\x14L\x9c\f[N\xc1q,$m\x8b\xae\v0\x1e\x15\xe7\xc0\xb6z\xe7\xaa\xe5\x94[\xa0*\xf8\x16\nf\xa0\x80\xcc*\x1d'O\x8a\x10\xb8\x92\xaa?#\x94\x1dѤ\xfd hV\x89\xb6\x05\x03̽\xc8\xf6\xce\xddD)#X,W`Hc\xf0\xaa*\"V\xa8-\xb3\x92\xe1;\x9bS\x1amIP\x1fC\xb81EҖD\x1dܖ\x19mܧz#6oD\xef\xa1)\x9f%웓\xe6//\xecHn\x01\x86\x9c>\U000bab98\xb0\xe1k\nԞ\x1fh\xfe\xce\x18w\xdel\xd9\f[\xbf\xf8ly\x11\xae5h\xfc\x9d0\x8d\x8c՝\xb7U\x8b\x18\xf6s\xb7\xe5\x15\x13\xbb\x86a\xf9\x15ۉ\xc2\x02\xf9Rs\x88v\x1c\x9dYν$\x81Rm/\x96\x92\xdbl\xff\xa9Y\xd6Nh1\xa0\xd5\x10\x80\xf3\xcbC\fC\f<\x9d.\n4\xc0$\x90\x9dA\x91\x9b\xd6\xc4xn?\xef\x8aq\xf6\bG\xe7Y\x8d.\x0f\x8d\x15d-o@j\xa0\xcdER#\x8fp$P~\xb70\t\xde\x12Qq\xe5\x11\x8e\xa9U\aDE\xfc\xfc>\x85\xa3.~\xa0Q\xa4L\xa5\xb64D\xf5s\x87Y\x956X\xb6L)\x85\x12(~\xe6\xb0\x1b\x86\xf5\xb6\xc8\x1f\xe1\xf8\x83q\xec\xc3Y\xb3\x17\xd5\x02\n\xa0¦%\x19\xb5k\xf6\x86\xbf\xf1B\xe4Mg4O\x16@\xdc\xc8+\xf6YY\xfc\xe7\xd3wa\x10E\x99\xb3\x8f\n\xccge\xe9˫\x92\xd8\r\xe2L\x02\xbb\xc64-\xa53\vH\x97E\xfd\xb78\x90\tE\x11m\xd8&\f\xdbH\x8c\xcf\x1c}\x96\xb0i\x0f\x019\x87VY\x1b\xda]\x96J\xaeܒ\x96\xefm\x01\xd0.^\x9eUJ\xf78u\xb5\x10\xe2(\x8a\x1e\xbd{\xb4V\ue5d3}\xf9\xa9\xa2\xa1*x\x06y\xd8e\xa3$\x00n\xe1Ad\xac\x04\xfd\x00\xacB\xbb\x91.T\v4\xb9+gHa\xbak\x11\x8a7\v#{\xdace\x85\xb3>\xb1f`sR\xf5Ȏ\xfft\xf5\xb4Q\x92y'\x7f(\x89\xfa\xdd\x14\xb5e\x96e!\xbfN}\x10\x87\xa4s?JN\x1bO\x7fE\xf3J\xe2\xfd\xb74kȅ6k\xf6\x81\x12\xf4\n\xe8\xb6\x0f\xab\x84\x9d\xae\x92@\"&\xc20\x94\x93\x03/\xd0}@\xe5-\x19\x14ΙP\xbb\x13\x0f*M\xc5<\xed\x95q6\xbf\xd9\x18\xbb|\x84\xa3ߜ\xedj\x89ˍ\x8c\xae\xda\xf7\v\xea\xfc\x13\xa5\xd5x-J\x16GvI\xbf]\x92c\xb6d\x8a\x9c\xe1\xbc-\x90\xea\x05U\xbf\xaf\x1e\xeb-h\t\x16̪\xe4\xd5\xca\xcf\x06\xab\xca\xe8\x1e\xa7+\x94F\xb7$\x8c\xc08=x<ظI6C\xf7\x7f\x8e\x02\xc9\xf3\xa1R&\x92i\x11A\xebV\x19\xeb\x16\x0f{\xae\xfa\xc8\xeabJ\xe4\xe8W\x1c\x19\xdfY\xd0\xccX\xa5Cb\x17\xaa\xec\xc1\xe2:J\x8d\x99\x97\x1b\xb7O\xe4W2\x1d`\fP/[\xed\xe2\xec\xc1\xa5۫\xc2\xff\xcf\xc3\xcc\xc8\xd1\"ؕV\x19\x98h6B[\x12\xad\xce\xccbo\xb3\xd0\xcb]\xe0\xb7KR\xeb)\xcbС,s㑴g\x04E\x9f\xbew֬Q\x85\xe1\xdf)\xa2|\x0e\x8e\x8cr\xbb˒\x0f\x93\f\x93ѽq\xad\xc3\x04\xf4\xc0\\\xb0\xa5\x1fjRH\xcb|n/\x92\xbf7\xa7\xa5\x14rC\x1d\xb1\xf7\xaf\xe6\xe8\xb0`\x06b\x19Ice\xc0\x0e߾eH\xf3!5\xf6e!UM\xd1>\x8f\x86\x1egOwA\xd29\xc5\xd0\x11\x97\xcav\x17z|O?\x18\xb6\x13\xda\xd8\x16\xe1\x05P\x85\x99\xc8z\x1a\x1d\xde\x19\xf1\xa9\xfc\xa4\xf5\xd9\xe1\xe9\x17\u05fa\xb3$\xb9WO>\xc1sIP\x1e\x88\xbf\xe7\a`bDŽe 3UKZ,Cu\x81\xdd,\x80\xe8\x98\xe8\x8cI\xa2\xcd\xec4\x96u\x99N\x90\x15I\xa7\x90\xb3+k\xdd&?q\x91\xb6\xb2\xc5\xcec\xab\x9dJ\xa2\x1c+\xfd\xccP\x9fM\xd9\xcd\xe4-\xf9wQ\xd6%\xe3%\xb2eI̹sy\x98!\xed\xd7\xf1\xfa\x89\v\xebOS\xb8M\xd9e\xda4SeU\x80\x85\x90a\x99)iD\x0e\x8d\xfb\xe0\xf9?\x9a\xaf\x1a+\x9c\xed\xb8(j\xbd@G/\xe6\xccҘϫ\xa7\x97\x0f\xe4\xd2\x11Y\x111\x13\x17\xec\x178\xdc\xf3\xf6\xa3\xd2\xcb\\\xe6[\r/\xef\x9aVZ(ʁ\x9d\xf1Nga\x92\xf7\xda\xf7N\xbd\xf0ry\x8c\xb9\xa7\xb3P\t\x937\xf7\xb4)o\xee\xe9\x9b{\xfa\xe6\x9e\x0eʛ{\xfa枾\xb9\xa7\xe3\xe5\xcd=\xed\x947\xf74\xd9~\xa4`\xb8\xa2\x95ۉ\nIX%\xa6o̡=ӗ\xcfR\xf2gA\x96dWo\xc6[\x8e\x9c\x05Zt\x86\xc4t\x8c^\x93n\x8dS2L&w\xa64\xc1\v\x7f\x81\xb36\x01\x81\xb3\xcf\xdal&\x01\xbc\xe0Y\x1b\x8f\xe9p\xed\xfc\x05O\xda\x04Z,?\x84q\xe5ӘJ\xe0aK\xc8\xe5\xa0\xe4\xb1nc^l\x0f\x8f\xd1:\xbfq\xd6\xfdI\xb6\xe6\xf9\"\xf3\xffr~'\"6'\xa7S#P\x85A\xb9\xfacp\xe2,\xdaG\xa9\xed\xfe\x17\x1b]KX\xa7x\xdd5\x03\xddT\xcb~\xca\xeb\x1fG\xb0ϑ\xe4\xd4\xf371\xe7<\xae\xdb:\xc4Խ\xf3\x1e\xbfoZZ(\xbfTޒ\xa5\x9f{ߌ4{\xc6\xc9wn\x8e2\xdbk%Um\xfc\n\x0f\xf6\xf0!sW\x01\x84\x8e\xcc\x12e\xf0\x9e\xedU\x1d9\xe31Cׄ\xcc\xdbx\xbe\xad\xcf\xe0\x00\xcb\x0f\xef\xd7\xfd_\xac\xf2ٷ\x11\xac\x9f\x84ݻ\xfb\x18x\x9e\xa3\xa3\xde9\xe2\x13&\xaf\xbf\x93e(x\x11\x88J3)\n'\x95\x01B߀~\xa9ܒ\xdf\xd9~\xcb\xfc\xc2Sz\x8e\xee\xd2\xcc\xdc&\x97r\xdeK~F>\xee\xb2\xc3R\xb3\xb9\xb7)H\xb3\x94\x8c\xdb\xf1\\\xda\x19\xa8K\xf2lS\xd7\x14\x13rj\xd33i\xd3\xc8\xc3\xe8&\xa5\xd4\xfc\xd9\xe4(45W\xf6u2d\x13\xf3b;ٮ\xb3 \xcf̆M&XZ\xe6kr\xbek'\x8bu\x9eZ\x13Y\xae㹫\xb3 \xc7r[S2V\x93pM\xceSm\xb2O\xe7wF\x9e\x95\x9d\xfa\xf2\xe7`^r\xddb:\xd74)\xc34imc\x1e\xe7\xa4\x1cҥ\x99\xa3IT]\x9a%\xdad\x80Nt\x9c\x94\x1bz\x9a\xf795\x94ٌ\xd0x\xb6\xe7\x14ر<Є\x1c\xcf\t\x90\xdd\xec\xcf\xc5n\xc0\xac4\xcdVX\x9a\xbb9~?Z(\xf3ֹ\xf8-d\xf6\xb9dR\xba\xe74\xa7\x04w_\x06MPZ\x82\x9f8\xe6\x88\xc7Ce瞟\xe1\x88G@nv\xac\xac\v+\xaa\xa2sA\x99\xddñ\xb9\xf2\xe7WE\a\u05f7G\x82\xf6\xe5k#\xf21\x90\xfd\x90\x82\x1b\xf6\x04E\x81\xff\x9eP!s\xd7\x01fj\x05h\xa5\xe2\x1b\x81\xfe\xaa#\x7f\x97\xe0\x95[\x16\xa3S\xfdd\x01K\x844}\x01֤)\x99v\x8f\x9dWO\xdf\xfeR\x83>2\xbas+\xf8AQ1kO{\xfa\xc9l0&\f\xca\xc7k1w)e_\x19\xc5gC\xa3\x02\xd8\a\xe9\f\xf3\x10W\x82\x85Z\xa7\r\xa7\xa6\x94-FO1\x10R5\x10\"\xedS\xbc\xef%\xc7\x1f_#\xb8z\x89\xf0*\xc9\x11y\x8d\x10뵂\xac\xa5a֒䍤㋯\x11l-\t\xb7\x16\xf9\x8c\xe9\xc7\x13_\xebX\xe2+\x84]g\a^\x8bH\x97z\xecpq\xf8\x950\xbe\x99c\x86'>Z\x02\xc8\xe8\xf1\xc2\xf1\x10,\x01\xe2ɱ\xc2\xd9 ,e\x1e\fôg\x1f\x12LNdZ\xb4\x9b\x9e\x9a\x84\x94\xb6\xd1=\x7f\xf8/\xf1\xd0_\xe26x\n\xf6\x89\x87\xfb\x96\x1f\xeaK\xa4\xf3\x99\xe1\xd9d\u05c9\x87\xf7\x16\x05hg\x86h\x93\x10\xa7\x0e\xebM\ai\xd3\vp\xc3Czg\xb8\x13\t\x12\x96Pe\xf9A\xbbgo\xc6(\x9d\x83\x9e\xdd\xd7Z\"γ\x82<\x88\xa3\xfa\xfd\x0fvt\u008d\xa8X\xab\xbbg\x16\xe3\xa8j\xee\x1d\xc9؟\x84\xf4\xbb\xf5(\xb8\x1d\x9f\xa4\xb7\xf1\xd6:L\xf1}\x9d\xd6K\xf5\x17\xab\xbb\x1d;\x03\x15״\x8f\xbf=\xba\xa4 \xb3f\x9fx\xb6oz\x88\x80\xa4~\xf7ܰ\x9d\xd2%\xb7\xec\xb2\xd9\n}\xe7:\xc0\xbf/\u05cc\xfd\xa4\x9a\xf4\x91νb\x11\xa8F\x94UqĈ\x89]v\xc1ti^\xd6ɂ\x88\xc5(\xd8\\\xf8\v\v\a\x97\n\xefTQ\xa8\xa73\x97.x%\xfe\x8b\xde1I[\x1b\xfbp\xbb\xa1\xeaA\xaa\xe8\r\x94&{\xae\x91\xb1-L+\xf4v\xe0\xe4zt\xa1\x8ed\xaf6\x7fN@\xa4W\x04\x82\x9f\xe1\xd5x\xa6P\x8b\xddn\x1c\x96k\x12,.\x8fL\xf9{\xe2\x85\xceW\x15\xd7\xd1M=\xe6\xe5\xc1\\\xf50\fv|n\x05kҬ\x9d\xbe\x8a\xd0-=\x9a\x87\a\x12h\xb3\xf7X\xf5\xb7щ\xd2\x1dz>\a\xa7\xe9\x83˳G\x96_\x01\xa7i\x97iET\x8c\xfc\x14M\xc7{\xf1\xd5C\xe3/\x91\xffE\x1d\xe0ct\x15\xb1\xffd\xc0\xa0\xc9H\x02]\x80:umz\x9b5\x17\xbf\xce\xfa\x052\xe2\x02*\xfe\xe2\xeb\x05\xe3\xf3-\xc6^i\xf0\xf7\x7f\a\xd8\x13\xb6\r\xa7\xec\xed7\n7\x1bu\xe9g\xb8\x0f&\xc3R\xe1\xe0\xaa\xd6\b\xc8\xd83\v/E-\xab4\x7f\x80\x9f\x95{\t#\x85Z\xfd\x16\xbd\xc7P\xbc3\x17\xb2\x89\xfd\\\x8b)s?\xb6!\xc0\xf6\x90\xc1\xc9u\xf4\x88홷\xed[[$\f\xee\xfe\xfeg7 +JX\x7f\xac]\x86\t\xea]\x03H\xe90P\xd7h\x1b\xd7N{\xf5D\xf7\xb9w\x9f\xab\xe8<\b\x04t\xa8\x81\xd2F\xcf\x1aM]\x15\x8a\xe7\xa0o\x94܉\x87\x84\x81\xfd\xb9\xd7``\xd93\xfa\xe8\a\x1b\xeccd`\xa1\xe7W\xcc\fA\x97\xad(\xa0\xf8I\x14`\x1c≊\xfe\xf6\xb4e\xa3\xf7\xebr\xeb\x1c\xd4\x1d\xfe\xd8t2aM\xddPiM\xbf\x02\x8d\x8e\xa0[\xfd\xafM\x10\xf0ib\xb0\x86\x8fBZx\x88$\xf8\xcch\xf8C\xef\xe9\x8f0IR\xd4ڷ\xf1\x96\x1do\xb93]\xa7\x92\x05\xd5.\n\x8b\x1b\xa32A\x0e6\xed\x8eЩ\x91\u05fbsz*P\x9a\xa0cm\xe0˓\x04\xfd5\xa8d\xb3\x91\xb1\xb76\xfa\xb3\xe6\xa4a\xf4\x9d\r\xabȭ\x1fT\x1f\v\xe7\xa4'\x90q\xaf\xb4\x84m\x1ea\x9a\xb7yNI73\xaf\xe2Z~\xdc'Y\x8d?\x87\xb3j^\xe8\xb9H\xa0\xac{\x85\xa6\x0fx\xfc\xf1%\xf7\\M\xc6+[\xeb\xa0rjM\x17p#\x10p\xf7S\x9f\xf7\xfcR\xfb\x9c\xdd\f/\xdb\a\xeeڅ\xef\xd9\xe7\xf4F\xf8\xd7<\xa0\x14}Qȅ\x8c\uee7b\x15\xc2?\x8f\x9d\xa3\xf3\x80.,\x9f\x19\xe9-\xd6iN\xfcyBS\xc3p\xd1\xf9]\f\xf5\xf1#\\+\xf6\x19NC\xb6\x15\xfb$q\x10\xa7\x9e\x9c;\xa7\x059-\x97\x8f==79\xc4Cӊ\x0eɍh\x8b\xbe\x9a\x1bT\x1f\xa4\xf0\xd2\xc35M\x15w n\x8c\xad\xff,vn/#\xc31\xfd\xcbI\x8d\xa8\xe2\x9aTZ1\x855:\xa5N>\x1a\xd0\az)&\b\x89\xf7ֺ_\xeam{\xef<\xfb\xeb\xdf.\xfe/\x00\x00\xff\xff\x89~\x02\xaf\x9ft\x00\x00"), []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xb4V\xcfo\xeb6\f\xbe\xe7\xaf \xb0û\xcc\xce\xebv\x19r\x1b\xba\x1d\x8am\x0fE\xf3л\"\xd3\tWY\xf2H*]\xf6\xd7\x0f\x92\xec&\xb1\x9d\xb5\x1b0\xdd\"\xf1\xc7Ǐ\xe4\xe7TU\xb52==#\v\x05\xbf\x01\xd3\x13\xfe\xa9\xe8\xd3/\xa9_~\x90\x9a\xc2\xfax\xb7z!\xdfl\xe0>\x8a\x86\xee\t%D\xb6\xf8\x13\xb6\xe4I)\xf8U\x87j\x1a\xa3f\xb3\x020\xde\a5\xe9Z\xd2O\x00\x1b\xbcrp\x0e\xb9ڣ\xaf_\xe2\x0ew\x91\\\x83\x9c\x83\x8f\xa9\x8f\x9f\xeb\xbb\xef\xea\xcf+\x00o:܀ \xa775\x1a\x85\U0004f222R\x1f\xd1!\x87\x9a\xc2Jz\xb4)\xfe\x9eC\xec7p~(\xfeC\xee\x82{\x9bCms\xa8\xa7\x12*\xbf:\x12\xfd\xe5\x96ů4X\xf5.\xb2qˀ\xb2\x81\x1c\x02\xeb\x97s\xd2\nD\xb8\xbc\x90\xdfGgx\xd1y\x05 6\xf4\xb8\x81\xec\xdb\x1b\x8b\xcd\n` $Ǫ\x06.\x8ew%\x9c=`gJ\x12\x80У\xff\xf1\xf1\xe1\xf9\xfb\xed\xd55@\x83b\x99zʹ.T\x06$``@\x01\x1a\xc0X\x8b\"`#3z\x85\x82\x12ȷ\x81\xbb\xdcɷ\xd0\x00f\x17\xa2\x82\x1e\x10\x9e3\xe5Ce\xf5\x9bIϡGV\x1a\xd9\x18\xdc\xceCvq;\xc1\xfa)\x95S\xac\xa0IӅ\x923\r\x94`30\x00\xa1\x05=\x90\x00c\xcf(\xe8u\x8a2\xf3ӂ\xf1\x10v\xbf\xa3\xd5z\xe0AR\xb3\xa2k\xd2P\x1e\x91\x15\x18m\xd8{\xfa\xeb-\xb6$BRRgt\x9c\x93\xf3!\xaf\xc8\xde88\x1a\x17\xf1[0\xbe\x81Μ\x801e\x81\xe8/\xe2e\x13\xa9\xe1\xb7\xc0\x98\xc9\xdc\xc0A\xb5\x97\xcdz\xbd'\x1d\x97ˆ\xae\x8b\x9e\xf4\xb4\xce{B\xbb\xa8\x81e\xdd\xe0\x11\xddZh_\x19\xb6\aR\xb4\x1a\x19צ\xa7*C\xf7y\xc1\xea\xae\xf9\x86\x87u\x94OWX\xf5\x94&K\x94\xc9\xef/\x1e\xf2B\xfcC\a\xd2:\x94\xf9(\xae\xa5\x8a3\xd1\xe9*\xb1\xf3\xf4\xf3\xf6+\x8c\xa9s3\xa6\xecg\xdeώrnA\"\x8c|\x8b\\\x9a\xd8r\xe8rL\xf4M\x1fȗ鲎\xd0O闸\xebHe\x9c\xddԫ\x1a\xee\xb3\xe2\xc0\x0e!\xf6\x8dQljx\xf0po:t\xf7F\xf0\x7fo@bZ\xaaD\xec\xc7Zp)\x96S\xe3\xc2\xda\xc5\xc3(s7\xfa\xb5\xb0\xdd\xdb\x1em\xea`\"1ySK6\xaf\a\xb4\x81\xc1,\xb9\xd4\x1fB\x92=\xfe%\x96AI\n\x9a\x89\xbe\xa4\xfd|\x1fͲ\x9c䗃\x11\x9c^N0=&\x9bi~G-ړuXB\x145\xc1\xf7\xa1\xa4\x83>v\xf3\x9c\x15|\xc1ׅ\xdbG\x0eIY\xb3\xae_\x9f\x1b\xb3\x01\xe5{\xb3'?+wZY\xb1\xca߰K\xa9\xbe\x10\xe8!\x10p\xf4>\xed\xedL!3\x90\xa9\x92\xcflH\xb1[@\xb3\x88\xe7\xc1\xb7!\x7f\xf0MJl\xb4\xec\x13\x0e\xcd\x1e\xf2\x14\\\v\x01o\xf7\xba\x9c\xb9x}\x88\xd0r\xf2\x97\xf4\xbf9'\xb9!\xc6\xc5\xdcUF\xb5\xf8\x902.1\xbe\xbc_\x03\xca\xe8\x9c\xd99܀r\x9c{\x17_\xc3lNө\x19G\xed+u(j\xba\xfe\xbd\x01\x9a9\xa4=y=\xa0\xbf\xb5\r\xf0j\xa6*\x7f\x95\x19v\xa7[\xae\xf7o\xff\x01\xe7+UFw\x03I\xbb+\xa5\x05\xce>D\xcab\xf7\xcaH/\xfe\xf3\x98\x11\xb2\xbd\xb4\x1d5\xe3j5\xc6?\"\xf3\x1anBXl\xf6\xec2\x87o.\xca\x13\rl\xf6c\xc1\x7f\a\x00\x00\xff\xff\xb1J-\xe7\xa6\v\x00\x00"), []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xb4VA\x93\xdb6\x0f\xbd\xfbW`&\x87\xbdDr\xf2}\x97\x8e/\x9d̦\x87L\x93f'N\xf7N\x8b\x90\x8d\x9a\"U\x10\xd4\xc6\xfd\xf5\x1d\x90\xd2\xdak\xcb\xc9n\xa7\xd5\xc5c\n\x04\x1f\xde\xc3\x03UU\xd5\xc2\xf4t\x8f\x1c)\xf8\x15\x98\x9e\xf0\x9b\xa0\xd7\x7f\xb1\xde\xff\x14k\n\xcb\xe1\xedbOޮ\xe06E\t\xdd\x17\x8c!q\x83\xef\xb1%OB\xc1/:\x14c\x8d\x98\xd5\x02\xc0x\x1f\xc4\xe8rԿ\x00M\xf0\xc2\xc19\xe4j\x8b\xbeާ\rn\x129\x8b\x9c\x93OG\x0fo\xea\xb7\xff\xab\xdf,\x00\xbc\xe9p\x05Cp\xa9\xc3\xe8M\x1fwA\\hJ\xcez@\x87\x1cj\n\x8b\xd8c\xa3Gl9\xa4~\x05\xc7\x17%\xc5x|\x81~\x9f\xb3\xad\xc7l\x1f\xc7l9\xc0Q\x94_\xbf\x13\xf4\x91\xa2\xe4\xc0\xde%6\xee*\xb2\x1c\x13w\x81\xe5\xb7\xe3\xe9\x15\fѕ7\xe4\xb7\xc9\x19\xbe\xb6\x7f\x01\x10\x9b\xd0\xe3\n\xf2\xf6\xde4h\x17\x00#?9]5Q\xf3\xb6dlvؙr\x0e@\xe8ѿ\xbb\xfbp\xff\xff\xf5\x93e\x00\x8b\xb1a\xea%\xb3<_\"P\x04\x03\x13\x12x\xd8!#\xdcg>!J`\x8c#\xe8Ǥ\x00\x13\xfeX?.\xf6\x1czd\xa1\xa9\xf8\xf2\x9c\xf4\xd7\xc9\xea\x19\xae\x1b\x85^\xa2\xc0jca\x04\xd9\xe1T>ڱZ\b-Ȏ\"0\xf6\x8c\x11\xbd\x1c\x85<>\xa1\x05\xe3!l\xfe\xc0FjX#k\x1a\xd5&9\xab\xfd8 \v06a\xeb\xe9\xaf\xc7\xdc\x11$\xe4C\x9d\x11\x1c5?>\xe4\x05\xd9\x1b\a\x83q\t_\x83\xf1\x16:s\x00F=\x05\x92?ɗCb\r\x9f\x02#\x90o\xc3\nv\"}\\-\x97[\x92\xc9WM\xe8\xba\xe4I\x0e\xcbl\x11\xda$\t\x1c\x97\x16\at\xcbH\xdb\xcap\xb3#\xc1F\x12\xe3\xd2\xf4Te\xe8\xbe\xf8\xa0\xb3\xafxtb\xbcy\x82U\x0e\xdaEQ\x98\xfc\xf6\xe4E6\xc2w\x14P\x0f\x94F([K\x15G\xa2uI\xd9\xf9\xf2\xcb\xfa+LGg1\xce\xd9ϼ\x1f7ƣ\x04J\x18\xf9\x16\xb9\x88\xd8r\xe8rN\xf4\xb6\x0f\xe4%\xffi\x1c\xa1?\xa7?\xa6MG\xa2\xba\xff\x990\x8ajU\xc3m\x1e6\xb0AH\xbd5\x82\xb6\x86\x0f\x1enM\x87\xee\xd6D\xfc\xcf\x05P\xa6c\xa5\xc4>O\x82\xd39y\x1e\\X;5\xd88ޮ\xe85\xef\xe4u\x8f\xcd\x13\x03i\x16jitv\x1b\xf8\x8cW3\xf9|>_\xfd$|\xde\xe0P\x86|K\xdb\xf3U\x00cm\xbe\"\x8c\xbb\xbb\xba\xf7;\x84\xcd\xd4}\x9bO\xd2Fm\x03+\xa2\x81,r5\xd59\"I<\x16L\xe8l\xac/R^\xe1<\x97\xc2hUc\xe3.\x81>E\xf2\x18\x98\xef8C\xbeP~L\x90[\x8f\xbbq\xc6zAo\xf3P\xbf@\x13r\x0fG\xb4\xf0@\xb2+\xe6p\xa7\x97\xd4\xf3T\xd0g\x8f\x87\xb9\xe53\xec_w\xa8\x91e\x9c\"Dl\x18EqDtj^uf\r\xf0)\xc5l/3\x9b\x11tD\x90\x9dv\xef\xf1pI4\xfcH\xdc\xf1\xbe\xff1\xe4\x1b\xbd\x17'\xc0\x8c-2z\x99\xb5\xb8~b\xb0G\xc1\xecr\x1b\x9a\xa8\x06o\xb0\x97\xb8\f\x03\xf2@\xf8\xb0|\b\xbc'\xbf\xad\x94\xf0\xaa4B\\\xe6\xef\x86\xe5\xab\xfcs\xa5䯟\xdf\x7f^\xc1;k!\xc8\x0eYUk\x93\x9b\x1a\xed\xe4\xb6{\x9d'\xeekHd\x7f\xbe\xf9'\xbc\x84\xbe8\xe7\x19ܬs\xf7\x1f\xf4\xe6Π\x94\xa2uQ%0\xe8\xdcT\xb1\xbbQ\xcd2\x1f\xe6\x1aq´\t\xc1\xa1\xb9l=\x9d\xbe\xc4h/!Uz\xc2Kl\x06\xf0\xad:\nUu\xa6\xafJ\xb4\x91\xd0Qs\x16=\xf9\xfc\a\x96\xbc\x1b\xc3t<(\aӶ\xa9m\xcaWL\xfe\xa61[\xbc6\x16f\x14\x99/\xbcz<\xe0Y\x03]\x8c\xa4\xf8\U000917b7\x8d\x91\x9bq\xac7\x89\xb5\xfdǜ3\x9f?\xff\xceX\xefw&\xcex\xf3\x19\xa8\xeft\xe7$\x83\xa3\x16\x9bC\xe3\xb0$\x84\xd0\xce\xf4ދ \xeb\x83>us\x8d\xf8n0\xe4\xcc\xc6\xe1̻߽\xb9\xfa\xf6\xaa\xf8\xb3z^,F\xfdƱ+\x10N%\xf7\xd8e\xe3\xca\xdf\x01\x00\x00\xff\xff\xec\xa0\xe0\xa1k\r\x00\x00"), } diff --git a/config/crd/v2alpha1/bases/velero.io_datauploads.yaml b/config/crd/v2alpha1/bases/velero.io_datauploads.yaml index 9f873afad..324a98181 100644 --- a/config/crd/v2alpha1/bases/velero.io_datauploads.yaml +++ b/config/crd/v2alpha1/bases/velero.io_datauploads.yaml @@ -125,6 +125,14 @@ spec: description: SourcePVC is the name of the PVC which the snapshot is taken for. type: string + uploaderConfig: + description: UploaderConfig specifies the configuration for the uploader. + properties: + parallelFilesUpload: + description: ParallelFilesUpload is the number of files parallel + uploads to perform when using the uploader. + type: integer + type: object required: - backupStorageLocation - operationTimeout diff --git a/config/crd/v2alpha1/crds/crds.go b/config/crd/v2alpha1/crds/crds.go index acbdbed1f..f68d2ce64 100644 --- a/config/crd/v2alpha1/crds/crds.go +++ b/config/crd/v2alpha1/crds/crds.go @@ -30,7 +30,7 @@ import ( var rawCRDs = [][]byte{ []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xbcY_s\xe3\xb8\r\x7fϧ\xc0l\x1f\xf2\xb2Rn\xaf\x9dN\xc7o\xbbN;\x93\xe9m\xea\xb9\xec\xe4\x9d\x12a\x99\x17\x8adI\xc8i\xda\xe9w\uf014d\xfd\xa1\xe3d\xafwz3\t\x82?\xfc\x00\x02 ]\x14ŕp\xea\x11}P\xd6l@8\x85\xff\"4\xfc+\x94O\x7f\t\xa5\xb27\xc7OWO\xca\xc8\rl\xbb@\xb6\xfd\x19\x83\xed|\x8d\xb7\xb8WF\x91\xb2\xe6\xaaE\x12R\x90\xd8\\\x01\bc,\t\x1e\x0e\xfc\x13\xa0\xb6\x86\xbc\xd5\x1a}Ѡ)\x9f\xba\n\xabNi\x89>*\x1f\xb6>\xfeP~\xfa\xb1\xfc\xe1\n\xc0\x88\x167\xc0\xfa\xa4}6\xda\n\x19\xca#j\xf4\xb6T\xf6*8\xacYq\xe3m\xe76p\x9aH\v\xfbM\x13\xe0[A\xe2\xb6\xd7\x11\x87\xb5\n\xf4\xf7\xd5\xd4O*P\x9cv\xba\xf3B/\xf6\x8e3A\x99\xa6\xd3\xc2\xcf\xe7\xae\x00Bm\x1dn\xe0\x9e\xb7v\xa2F\x1e\xebm\x8aP\n\x10RF\x96\x84\xdeye\b\xfd\xd6\xea\xae\x1d\xd8)@b\xa8\xbdr\x14Y\x98\u0082@\x82\xba\x00\xa1\xab\x0f \x02\xdc\xe3\xf3͝\xd9y\xdbx\f\t\x16\xc0/\xc1\x9a\x9d\xa0\xc3\x06\xca$^\xba\x83\b\xd8\xcf&*\x1f\xe2D?D/\x8c7\x90W\xa6\xc9!\xf8\xa6Z\x04\xd9\xf9\xe8B\xb6\xbbF\xa0\x83\nsh\xcf\"0\xa0\xc7(Q%\t\x8e^P\xec;볮sX\x97I\xb6W6\xe8Z\xf8o\xbe\xd1\xff=\xb6j\x8f\"\x1b[C\xaa)\xa3\x84\xb2&\x1f`\x9f\x1b|SpMI4Vℱ\x19&\x15\xc0y[c\b\xaf\x04<+\x98\xa1\xb8?\r\xac\xa8I\x12\xc7\x1f\x85v\a\xf1)%\x99\xfa\x80\xad\xd8\xf4+\xacC\xf3yw\xf7\xf8LJ\xd90\xbc\x920DM\x813\x05\xc3wޒ\xad\xad\x86\n\xe9\x19\xd1$\u05f7\xf6\x88\x9e\xf3\\\xa3L\x185r֖S\x81S\xce\xe6\xf8\x8e\xfax6Mz\x8c\xd1\xc3\x00\xfd\xd4\xfb\xc0{:\xf4\xa4\x86,\xdc\xeb>\x15\x98\xc9\xe8\u008ek65I\x81\xe4ʂɌ>\x97\xa2\xec\xd9I\xceR\x01<:\x8f\x01\r\xcd!\xf4\xdc\xedA\x18\xb0\xd5/XS\t\x0f\xe8Y\r\x84\x83\xed\xb4d\xe3\x8e\xe8\t<ֶ1\xeaߣ\xee\x00d\xe3\xa6Z\x10\xf6%\xe1\xf4\xc5\xdcm\x84\x86\xa3\xd0\x1d~\x8c\x94\xb5\xe2\x05<\xf2.Й\x89\xbe(\x12J\xf8\xca<)\xb3\xb7\x1b8\x10\xb9\xb0\xb9\xb9i\x14\r\x85\xb5\xb6m\xdb\x19E/7\x91oUud}\xb8\x91xD}\x13TS\b_\x1f\x14aM\x9d\xc7\x1b\xe1T\x11\xa1\x9bX\\\xcbV\xfe\xc1\xf7\xa58\\ϰ\xaeb-}\xb1&\xbe\xe2\x01.\x8c\x1c\xe8\xa2_\x9a\xac8\x11\xcdC\xcc\xce\xcf\x7f}\xf8\x06\xc3\xd6\xd1\x19K\xf6#暈\xe1\xe4\x02&L\x99=\xfa\xe4Ľ\xb7mԉF:\xab\f\xc5\x1f\xb5Vh\x96\xf4\x87\xaej\x15\xb1\xdf\xff\xd9a \xf6U\t\xdb\xd8m@\x85\xd09>Ⲅ;\x03[Ѣފ\x80\xbf\xb9\x03\x98\xe9P0\xb1os\xc1\xb4QZ\n'\xd6&\x13C\xa7s\xc6_ӓ\xff\xe0\xb0f\xd71{\xbcL\xedU_\x01\xf8\xf8\x8a\x99l9S\x99?\xb2\xfce\xab\xc0Rh\x81\xe9Kn\xcd\x00\xccLrm_\x8eB\x92\\)\x05\xd0gK\x98Gg\x83\"\xeb_N\x85\xac\\i8\xe3\x00\xfejaj\xd4\x17,\xd9F!PF2\x938\xc6\x1d\xa7\x88\xa4 b\xb2\xa6\xb1|.\xce\x13\x9c\xbe;\xe2U\x1c\xa8\x01\x89m2\xd9\x1a\xa3\f\x9c:<\x98vrK\xcb*k5\x8ae\xde\xe3\xd8\xfa\xcaIzk\xcd^5k\x1b\xa7\xcd\xe89\xc7_\xa0/\x13\x86\x93-\xd9\n\x8e9FR\xc4zQ\f\x01ɉw\xaf\x9a\xce\xe726\x7f{\x85Z\x86s\xbe\\\x9d\x8f\xc1\xe0\xb8\xcb\x05w\x8e(\x87\xe3ї\x97I\xcd#\x1b\xf3H\x88\x8d&Of\x10\xa6\x10,\xe1n?Ѩ\x02|\xf8\x00\xd6Çt\x19\xf9\xf01\x85k\xa74\x15jZx3\x1a\x9f\x95\xd6þ\xef\x8a\xe2\xb1\xfar\x03d;\xba@\xc0?\x16\xe2\v\x1e\x88;\xb3h;Yx\x16\x8a\xc6r\x97\xc1B\x85{N\xb1\x1e\xa9\xf3\x86O\x02z\xcf)'D\x95\xb6\xa3w\x19\x15\x8cp\xe1`\xe9\xee\xf6\x829\x0f\xa3\xe0\x90]\xeen\x87\xdc\xf2\x18\xbd0\xa6\x98^\x12\xc8\xe6\x1c\x8aC;#c1z\x1f\xdaX\x01ǫ\xdf%\xc8s\xe9\x01\xb7\xf5\xaaQ\xdcV\x98q\xe6\x94\xf2\x8e|U\xcc\x05\xa2\n\xd1>\x94й\x04\x9cS\fW\xd7\nA\xaa\xfd\x1e=\x1aJ\xf55m\xbc{\xdc^\x87\xd3&9\x9d\xfb\t\x86\xd8a\xb5\xc29\x94ܱ\xb3g{\xa2\xdeE\x11\t\xdf =F3.\xf0\xf3m\":\x90Õ\x9b\xafW\\\bz\xef&\x8d\xb0{\xdcr\a\x961c\xf7\xb8Fx\xbe\xcaAߊ\x9f\xf1\xe0\n\xe5\xca\x7f=\x9e\u05c8\xbd\x90N\x01\xdc\xf1\r;\xef\x1es\x85t\xa4\x03\xe8 \x88%\xfa\xab\x13T/Y\x9d0\x9c\x8fޝ߇\xb7~\x13\xe0\xed\xab\x88\xb7K\xc8g\xf0V/\xbf\x1a2\x17o\xe5Q\xaeQ\x17\xafx\xae\x00w\xcc\x0e\xd6o/Q\xf9\x9d\x8b|w\xb5\x90Y\xa6\xf8\xc5\xf4)Y.'\xe6\x99f1;=\x92ojC\xe3\xe5\xf6\xad\x8dhz\xb2\xea\xdd^w>\xa6\xa1\xfe!\x8boe\xdfՊ\xd6\xe9\thzۿԾ\xadW\xc4\xfb\x9e\x97\x93z'ƫl|r\x18ޙr\xfd\xdbI_Z\x1a\xd3#\xabC\txD\x03\xdcj\v\xa5Q\x0e:C\t߸\x1b\x8f\x17\x9f\xeb\xe5\x15)\xf2\xdd+\x8ae\x97{\xa6\f\xe8\xf5\xbaὉ\xaf;\x05\xabXI\x98NkQi\xdc\x00\xf9\xee\\\xff\x98=(-\x86 \x9aK\x89\xfak\x92JW\xc5~\t\x88\x8a\x9b\x8aeO{\x1dz߿\xabh\x18+/a\xb8\xb72\x020\xdf\xf1~\xf3.,\xb1\a\xbf\x00f\xc72\xb9\x98\x1f\xa1\xbd~=@ӵ\xb9\xcct\x8fϙ\xd1\xcfu\x8d.\x97-\v\xd8yt\xc2g\xa7V\x0f\xc7\xd3\xc9t\xd9\xc9%\xcea.\xabs|\x99\xcd\xcc\xfd-\x1e\x86w1\xdd\xe3\xbbD\xf6p;:X=\x1c\xe6\xf8xj\xba\xb6Bό\xc7\xe7ف\xfa!Kf\x0e\xa00r沓\x86\xb1'\x8c\xaa\xf8$s\x95J\x17\xb8\xa1K\x96*8-rEv\xb0d־\x9c\x0e\xc8\xea\xfd\xec\xbd\xfd\xca\xf8\x98\x9d/¹\x17\xe9\x9c\x17\xa6oˋ\xf9\xf1\x91\xfa\xb7\xd9\xe1\x95\v\xdd\xfcO\x83K-\xf5L\xf8R\x82\xef\xff\xafȥ\xf7i\xa6^\xe7\xe5\xf96\xbfgJ\xce\x12\xb5\x1a\x8c\xc8\xe5Dw\xff\xac2\x1d\xe9\xaa\xf1\xb1p\x03\xff\xf9\xef\xd5\xff\x02\x00\x00\xff\xffG\x0e\xcf\xec\xfa\x1b\x00\x00"), - []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xbcYOsۺ\x11\xbf\xfbS줇\\\"\xfa\xe5\xb5\xd3\xe9\xe8\x96\xc8팦/\xae'J}\x87\xc8\x15\x89g\x10`\xf1G\xae\xdb\xe9w\xef,@P \t\x89R\xfaR\x1e<\x16\xfe,v\x17\xbb\xbf\xfd\x01X\xadVw\xac\xe3Ϩ\rWr\r\xac\xe3\xf8O\x8b\x92~\x99\xe2\xe5O\xa6\xe0\xea\xfe\xf8\xf1\xee\x85\xcbj\r\x1bg\xacj\xbf\xa2QN\x97\xf8\x80\a.\xb9\xe5J\u07b5hY\xc5,[\xdf\x010)\x95e\xd4l\xe8'@\xa9\xa4\xd5J\bԫ\x1ae\xf1\xe2\xf6\xb8w\\T\xa8\xbd\xf0\xb8\xf4\xf1\xa7\xe2\xe3\xcf\xc5Ow\x00\x92\xb5\xb8\x06\x92\xe7:\xa1Xe\x8a#\nԪ\xe0\xea\xcetX\x92\xd8Z+\u05ed\xe1\xd4\x11\xa6\xf5K\x06u\x1f\x98e\x7f\xf7\x12|\xa3\xe0\xc6\xfeu\xd2\xf1\v7\xd6wv\xc2i&F\xab\xfav\xc3e\xed\x04\xd3i\xcf\x1d\x80)U\x87kx\xa4%;V\"\xb5\xf5\x96x\x15V\xc0\xaa\xca\xfb\x86\x89'ͥE\xbdQµ\xd1'+\xa8Д\x9aw\xd6\xdb~R\b\x8ce\xd6\x190\xael\x80\x19x\xc4\xd7\xfb\xad|Ҫ\xd6h\x82J\x00\xbf\x1a%\x9f\x98m\xd6P\x84\xe1E\xd70\x83}op\xdf\xcew\xf4M\xf6\x8d\xb45VsY\xe7\xd6\xff\xc6[\x84\xcai\xbfmds\x89`\x1bnR\xc5^\x99!\xe5\xb4\xc5\xea\xac\x1a\xbe\x9f\x84\x19\xcb\xdan\xaaO25(T1\x8b9u6\xaa\xed\x04Z\xac`\xfff1\x1aqP\xbaev\r\\\xda?\xfe\xe1\xbc'zW\x15~ꃒc\xb7|\xa6VH\x9a\x83&\xb4C5\xea\xaco\x94e\xe2\x7fQĒ\x80\xcf\xc9\xfc\xa0I\x90\x9b\xb6/\xaaB\xe1\x06\xea\x00\xb6A\xf8\xcc\xca\x17\xd7\xc1\xce*\xcdj\x84_T\x196\xef\xb5A\xddo\xde>\f1\x8dr\xa2\x82}\xb4\x18\xc0X\xa5\xb3\xbb\xd8aY\x84Y\xbd\xdc(v\xb2\x95\xe35\x7f\xe3 +5\xb2l\x90E\x94)\xfc\b\xaed>\xd2>\xd5xU\x94\xa5ޔ\xaa\xc2\xc1u\x98j\xc4\rtZ\x95h̅\xb8\xa7\xe9#\x1d\x1eO\r3\xb7\x84\x11ǟ\x99\xe8\x1a\xf61\xa0L\xd9`\xcb\xd6\xfd\fա\xfc\xf4\xb4}\xfe\xfdn\xd4\fg1\x83\x95\xd6\x10X\x90\xea\x9dVV\x95J\xc0\x1e\xed+\xa2\xf4\xb8\x05\xad:\xa2&\x90\xab\xb94\xc0d5Ȅt\xc0\t\xaa)Ƚ<\xea\r\x9d}8\xa9\x0eu\xba\xed@Kv\xa8-\x8f\xe8\x1b\xbe\xa4\xac$\xad\x13#ޓ\x9da\x14TTO0X\xd1c)V\xbdk\xc2>q\x03\x1a;\x8d\x06\xa5\x1d\xab\xd0;\xee\x00L\x82\xda\xff\x8a\xa5-`\x87\x9a\xc4\xc4\xf8/\x95<\xa2\xb6\xa0\xb1T\xb5\xe4\xff\x1ad\x1b\xb0\xca/*\x98ž\x1c\x9c>\x8fݒ\t82\xe1\xf0\x03\xf9\x0eZ\xf6\x06\x1ai\x15p2\x91燘\x02\xbe(\x8d\xc0\xe5A\xad\xa1\xb1\xb63\xeb\xfb\xfb\x9a\xdbXNKնNr\xfbv\xef\xdd\xcd\xf7\xce*m\xee+<\xa2\xb87\xbc^1]6\xdcbi\x9d\xc6{\xd6\xf1\x95W]\xfa\x92Z\xb4\xd5\xeft_\x80\xcd\xfb\x91\xae\xb3@\v\x9f\xaf\x85\x17v\x80J\"E9\xeb\xa7\x06+N\x8e\xa6&\xf2\xce\xd7?\xef\xbeA\\\xdao\xc6\xd4\xfb\xde柳\xe6\xb4\x05\xe40.\x0f\xa8\xc3&\x1e\xb4j\xbdL\x94U\xa7\xb8\xb4\xfeG)8ʩ\xfb\x8d۷\xdcҾ\xffá\xb1\xb4W\x05l<ǀ=\x82\xeb(\xbb\xab\x02\xb6\x126\xacE\xb1a\x06\x7f\xf8\x06\x90\xa7͊\x1c{\xdd\x16\xa4\xf4h:8x-\xe9\x88\f\xe7\xcc~\x9d\xd2~\xd7aI\x1bG\xbe\xa3I\xfc\xc0\xfb\x1a@\xb9˒\x91\xc5H\\>]\xe9\xcbB\xfft\xd0D\x9fϹ9Q-\x99@l\xacFa\xe4L(\x80\x98\x96\xb0a\x8e\xc6N\x19n\x95~#\xc1\xa1z\x153\tg\x9cO_\xc9d\x89b\xc1\x92\x8d\x1f\x04\\V\xe4G\x1cb\x8e\xe0!\b\xf0:)Y+ʉs\xee\r\xdf\xd6\xd2\x1c\nQ\x83\x96,\x92\x99\xc2\xc2%\x9c\xb8\x1d\xa4\x1cnj\xd5^)\x81l\x8aw\xa5\xe1;\xc9:\xd3(\xbb`\xdb\xf6\x00q䷷\x0ei\xf1\xcdn\xfb\x81\xfe\xc4v\x8a\x8b#\xafz\x00\xa6\xe4!\x963\aY\b@K\x836\xbb-\x98~\xfa\xdc\t\xd2\t\xc1\xf6\x02\xd7`\xb5\x9b\x1bv>\f\xe9\x8bb7\x82\x99쀉\x81\xbbt|.\xfc\xa2@(\xfd\b۰)\xd4\f\x1e\xa7\xfaCd=\x99\xc4\aZ\x02\xaf\xdc6ٙ\x17\xe2\x0fz\xd2\xc5j\xbcڠdx֞\x9e\x84\x05s\xd4\xe1\x821O\xcf\x1bo\xef\x92e\x04\xcb\xdfcY\x10y>\x12g\xb6=\x8f&䬛hy\xce8E\tF \x81\x15\xb8\xeev\xdd)ù\xc6j\xae\xf3j\xb4_\x99\xee\xb1\xd1g\xd2v\x06\xee\xd0\xf3\xad/Ĩ6J\x1ex=_;=:^ʑ\x8b\xa6͊F\xb2$y\x9cj\x04i\xb2\xf2\xe4n\x15\v\bѤ\x03\xaf\x9d>\x97\xfa\a\x8e\xa227g\xfb\x82?\xbc\x12\v\x186\x18\x11\xab]\x0fU\t\x7f\r\x01\xe1\x8c?9RgƀPS\n\x82ēDn\xe0\xdd;P\x1aޅ\x1b\x85w\x1fB\xfdq\\\xd8\x15OItF\xe2+\x17\"\xae{SY\x1a\xa84\x1dd\x94[\x02\xf1\xbfM\x86O\xfc`\xe9|\xe5m\xb7\n^\x19\xb7\x03w\xcd!x\x94e>\xc0\x1e\x0fė4Z\xa7%\x956Ԛ\x18\x84\xf1\"\x95\xcb`\xfb\x05\xa3LRg\x16\f\x9a\x96$o\x05\xfd?\xc5\xec4\xd13Ƹ\xee6\r=\x85\x1d\xeen\x96\x94\x1c\x8f\x8ez*\xcdkN\xe7\x029\xf4\x9cxK\x00\x87\x8c\xa6\xfd\xa9\xdcÕ\xc7ۂ\x98B$q\x04\x80'q\x94\xa1aq\x02p:wlvی\xccaF\xd5\xe7W&;\x17\xbd\xf1\xf4\xbc\xb9\xca\x0f\xa4J\x06\xaf\xa9\xf9\xb5\xe1e3\u07b7\xd9\x19\xc1\xeb\xc2^\xd0s\xd4\x1b\xd4\xcc\x03\xf5*\xcfX'c\xa6Y6\xe9N\xe3u\xda5\xde\xfal\xef\xd3\xf3\xe6*V\xef/\n\xae\xe3\xf5\xe1\x06\xb0\xf7r\xe9\xb4Fi\xe3\xbd \x1dq\xbf\x83ٗ\xe1F-\xbd3Yb\xc3\xf3\x19\xfe謫\x04mXd\xe8\xfe\xde&\xde\xda\xe5\xf8\xf0I\\\x98\xe9\x8f\xf2$\r+\xc0#J\xa0c\vゐۋ4\xc5tN>\x9d\x06)=\x8a\x85+\xdaxh\x8dw\x16\xfd\x95\xc07\nN\x7f&}o.\xc8\xf4 J\xe9\x97q\xc2<\xa2\xe3u \x9dDWY\xa1W\xd5\xc6lr\x0e\\\xe1+\x1a'2\x05\xe2\ar\x85\xb0d8n\x99,W\xb8|H`\x06\x18\xe8 \xa4\x87\x89Kg\xa6\xef'\x10-\x1a\xc3\xea%\x1c\xff\x12F\x85\xab\x8e~\n\xb0=\xd5ѱj\xefM\x9fl7\xc1\xa8TՒ\x06\x8f\xaa\xf2\xcb˛/\x1eoҤc\xb6Y\xd0\xe4\x89\xd9&\x02\xcc\xc1\t\xe1\xe7̪nO\xc2\xf7H\xd9\xf4[\x15_\x7f\xca]R\x8f\xc6\xe4\x00\x10\xaf\t$\x94\xae\xcd\x11\xfaG|ʹ~*K\xeclƲ\x154JDd\xf7\x0f\x13ҵ{\xd4\xe4o\xff\xf41>\x98\xe5\xb2]V\xa3\xedJ\xe6\x0f\x84\xc7K\"\x14\xa6Cg\xb8\x1d\x89|\xb5\xe2\xa6\x13\xec-#8\x1a\x92\xa2M\x92\xb7\xd3[\xe9y<\\\xbeh\x18\x9e\x89\xf2\xe7\xd6\xdc[On\x0f\xd2W\x9bI\xff\xf0\xfc\xf3cV\xb8\x00\x8c1\x93\xb7\x0fW\x12\xf1\xedC\xcc:^\xa1\xb4t\xb68\xbd\x04\x9cX\x9d\xbcx\xb4J\xae\xebn#\xa2\xa3\xc7\xc3%\x8dG\x83\x17\x98I\xffl\x99\xe3%;Jq\x02\x16\x7f'\xbd\x99>,}\x18ީ\x98\xed/\xc6ˆɚ\x12BRq\xf3\xc51'xF5F\xc4b\xac\xfe\xff\x93Sd\xc3e\xd6\xe85\xaf\x12\xd9\xfdmH\xda\xe2\xf6\xc3C\xc4\x1a\xfe\xfd\x9f\xbb\xff\x06\x00\x00\xff\xff?\xb7\xcf\xe0L \x00\x00"), + []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xbcYK\x93۸\x11\xbeϯ\xe8r\x0e\xbe\x8c8\xebM*\x95\xd2\xcd\xd6d\xabTYOT\x96w\xee\x10\xd9\"\xb1\x03\x02\f\x1e\x9aLR\xf9\xef\xa9\x06\b\n$\xa1\x97c\x87\x87\xa9\x11\x80nt7\xd0_?\xb0X,\xeeXǟQ\x1b\xae\xe4\x12X\xc7\xf1\x9f\x16%\xfd2\xc5\xcb_L\xc1\xd5\xc3\xe1\xc3\xdd\v\x97\xd5\x12V\xceX\xd5~A\xa3\x9c.\xf1\x11\xf7\\r˕\xbckѲ\x8aY\xb6\xbc\x03`R*\xcbh\xd8\xd0O\x80RI\xab\x95\x10\xa8\x175\xca\xe2\xc5\xedp縨P{\xe6q\xeb\xc3OŇ\x9f\x8b\x9f\xee\x00$kq\t\xc4\xcfuB\xb1\xca\x14\a\x14\xa8U\xc1՝\xe9\xb0$\xb6\xb5V\xae[\xc2q\"\x90\xf5[\x06q\x1f\x99e\xbfy\x0e~Ppc\xff6\x99\xf8\x95\x1b\xeb';\xe14\x13\xa3]\xfd\xb8\xe1\xb2v\x82\xe9t\xe6\x0e\xc0\x94\xaa\xc3%<і\x1d+\x91\xc6zM\xbc\b\v`U\xe5m\xc3\xc4FsiQ\xaf\x94pm\xb4\xc9\x02*4\xa5\xe6\x9d\xf5\xba\x1f\x05\x02c\x99u\x06\x8c+\x1b`\x06\x9e\xf0\xf5a-7Z\xd5\x1aM\x10\t\xe0w\xa3\xe4\x86\xd9f\tEX^t\r3\xd8\xcf\x06\xf3m\xfdD?d\xdfHZc5\x97un\xff\xaf\xbcE\xa8\x9c\xf6\xc7F:\x97\b\xb6\xe1&\x15\xec\x95\x19\x12N[\xacN\x8a\xe1牙\xb1\xac\xed\xa6\xf2$\xa4A\xa0\x8aỶ\xb3Rm'\xd0b\x05\xbb7\x8bQ\x89\xbd\xd2-\xb3K\xe0\xd2\xfe\xf9O\xa7-ћ\xaa\xf0\xa4\x8fJ\x8e\xcd\xf2\x89F!\x19\x0e\x92\xd0\tը\xb3\xb6Q\x96\x89\xffE\x10K\f>%\xf4A\x92\xc07\x1d\xbf(\n]7P{\xb0\r\xc2'V\xbe\xb8\x0e\xb6ViV#\xfc\xaa\xcapx\xaf\r\xea\xfe\xf0va\x89i\x94\x13\x15\xec\xa2\xc6\x00\xc6*\x9d=\xc5\x0e\xcb\"P\xf5|#\xdb\xc9Q\x8e\xf7\xfcΗ\xac\xd4Ȳ\x97,\xa2L\xe1Wp%\xf37\xedc\x8dWݲԚRU8\x98\x0eS\x89\xb8\x81N\xab\x12\x8d9s\xef\x89|$\xc3\xd3q`f\x96\xb0\xe2\xf03\x13]\xc3>\x04\x94)\x1blٲ\xa7P\x1dʏ\x9b\xf5\xf3\x1f\xb7\xa3a8\x89\x19\xac\xb4\x86\xc0\x82Dﴲ\xaaT\x02vh_\x11\xa5\xc7-h\xd5\x015\x81\\ͥ\x01&\xab\x81'\xa4\v\x8ePM\x97\xdc\xf3\xa3\xd90\xd9_'աN\x8f\x1dh\xcb\x0e\xb5\xe5\x11}×\x84\x95dt\xa2\xc4{\xd23\xac\x82\x8a\xe2\t\x06-z,Ū7M8'n@c\xa7Ѡ\xb4c\x11z\xc3\xed\x81IP\xbb߱\xb4\x05lQ\x13\x9bx\xffK%\x0f\xa8-h,U-\xf9\xbf\x06\xde\x06\xac\xf2\x9b\nf\xb1\x0f\a\xc7\xcfc\xb7d\x02\x0eL8\xbc'\xdbA\xcb\xde@#\xed\x02N&\xfc\xfc\x12S\xc0g\xa5\x11\xb8ܫ%4\xd6vf\xf9\xf0Ps\x1b\xc3i\xa9\xda\xd6In\xdf\x1e\xbc\xb9\xf9\xceY\xa5\xcdC\x85\a\x14\x0f\x86\xd7\v\xa6ˆ[,\xad\xd3\xf8\xc0:\xbe\xf0\xa2K\x1fR\x8b\xb6\xfa\x83\xee\x03\xb0y?\x92uv\xd1\xc2\xe7c\xe1\x99\x13\xa0\x90H\xb7\x9c\xf5\xa4A\x8b\xa3\xa1i\x88\xac\xf3\xe5\xafۯ\x10\xb7\xf6\x871\xb5\xbe\xb7\xfb\x91\xd0\x1c\x8f\x80\f\xc6\xe5\x1eu8ĽV\xad牲\xea\x14\x97\xd6\xff(\x05G95\xbfq\xbb\x96[:\xf7\x7f84\x96Ϊ\x80\x95\xcf1`\x87\xe0:\xf2\uea80\xb5\x84\x15kQ\xac\x98\xc1\x1f~\x00di\xb3 \xc3^w\x04iz4]\x1c\xac\x96L\xc4\f\xe7\xc4y\x1d\xdd~\xdbaI\aG\xb6#\"\xbe\xe7}\f \xdfe\xc9\xcab\xc4.\xef\xae\xf4e\xa1\x7f\xbah\"ϧ\x1cM\x14K&\x10\x1b\xa3QX9c\n \xa6!l\xa0\xd1\xd8)í\xd2o\xc48D\xafb\xc6\xe1\x84\xf1\xe9+\x99,Q\\\xd0d\xe5\x17\x01\x97\x15\xd9\x11\x87;G\xf0\x10\x18x\x99\x94\xac\x15\xf9\xc4)\xf3\x86om\x89\x86\xae\xa8AK\x1a\xc9L`\xe1\x12\x8e\xb9\x1d\xa49\xdcT\xab\x9dR\x02\xd9\x14\xefJ÷\x92u\xa6Q\xf6\x82n\xeb=ĕ_\xdf:\xa4\xcdW\xdb\xf5=\xfd\x89\xe3t/\x0e\xbc\xea\x01\x98\x9c\x87\xb2\x9c9\xc8B\x00ZZ\xb4ڮ\xc1\xf4\xe4s#H'\x04\xdb\t\\\x82\xd5n\xae\xd8\xe9kH_d\xbb\x12\xccd\x17L\x14ܦ\xebs\xd7/2\x84ү\xb0\r\x9bB\xcd`q\x8a?\x94\xac'D|HK\xe0\x95\xdb&Ky\xe6\xfeA\x9ft\xb1\x1a\xafV(Y\x9eէO\u0082:j\x7fF\x99\xcd\xf3\xca\xeb{I3\x82\xe5o\xd1,\xb0<}\x13g\xba=\x8f\br\xdaM\xa4<\xa5\x9c\"\a#\x90\xc0\n\\w\xbb\xec\xe4\xe1\\c5\x97y1:\xaf\xcc\xf4X\xe9\x13n;\x03w\xe8\xf3\xadϔQ\xad\x94\xdc\xf3z\xbewZ:\x9e\U000d1cea͂F\xb2%Y\x9cb\x04I\xb2\xf0\xc9\xdd\"\x06\x10J\x93\xf6\xbcv\xfa\x94\xeb\xef9\x8a\xca\xdc\xec\xed\x17\xecᅸ\x80a\x83\x121\xda\xf5P\x95\xe4\xaf\xe1B8\xe3+G\x9a\xcc(\x10bJA\x90x\xe4\xc8\r\xbc{\aJû\xd0Qxw\x1f\xe2\x8f\xe3\xc2.x\x9aDg8\xber!\xe2\xbe7\x85\xa5!\x95\xa6BF\xb9K \xfe\xf7\xc9\xf2\x89\x1d,\xd5W^w\xab\xe0\x95q;\xe4\xae9\x04\x8f\xbc\xcc=\xecpO\xf9\x92F봤ІZS\x06a\x85\x1dz7\x97\x84\x1c\xaf\x8er*\xcdkNu\x81\x1cf\x8eyK\x00\x87\x8c\xa4}U\xee\xe1\xca\xe3mA\x99BL\xe2\b\x00\x8f\xec\xc8C\xc3\xe6\x04\xe0Tw\xac\xb6\xeb\fρ\xa2\xea\xfd+\xe3\x9d\x17\xad\xb1y^]e\a\x12%\x83\xd74\xfc\xda\xf0\xb2\x19\x9f۬F\xf0\xb2\xb0\x17\xf49\xeaMb\x86\xd6\xdbi\xd0\x1c\xc9\xfa\xdbh\xf1\xc4OF\b7Թ\x91\xff\\\xa8\xf3\x89J\xc74\x13\x02\xc5/\\\xa0\t\xfb^\x11\x017s\xaa\xc1\xac\xaeݡ&\xc3\xeeir\xd8\xe0D\f웕\xe4\"\x1djJ\xdaB\xb6\xe9L,\xdcNk\x06٦\xd3|6\x03\xdb\xf9ȹȗ\x10\x935S؛L\xa7\x002\x9d\x1a\xfbbvv\U000fceaa\xcc\xf2\x9d\x9b\xeb\n\xadВ\xedϧtZ\xa3\xb4\xb1Q\xab\xf6\xdfTj\x95\xa1ř6\xb1.\x95's\n\xdf\xcb\xd0U\x02\xff,\x96L\xbe\x91\x16ۨ\xb9\x93?\xb2\v\x94\xbe\xb7Bܰ\x02<\xa0\x04\xf2\r\xc6\x05\x85R\xcf\xd2\x14S\x9a<\xbe\r\\\xfa\xb0\x12\xae_\xbc\x8c\xb1\x89\xd4\xf7h\xbe\x12Z\xf8&\xc1{s\x86\xa7\x8fj\xe4\xa9\x19#\xcc!&\xf6g+fq\x91ezU\xb2\x92\x85\xa1!y\xfb\x82ƉL\xc4\xfe\x81\xc9[\xd82Կ&\x9b\xbc\x9d\xafژ\x01\x06:0\xe9q\xfb\\\x11\xfb\xed\x19]\x8bư\xfaR`\xfd\x1cV\x85\xdeSO\x02lG\x89\xcdX\xb4\xf7\xa6w\xb6\x9b\x02\x86T\xd5%\t\x9eT巗7w\x82o\x92\xa4c\xb6\xb9 Ɇ\xd9&\x02\xcc\xde\t\xe1ifiP_\x15퐼\xe9{eC\xbe\xedpI\xcd\x1c\xd3ly\xb6\xd6M\xfa\xa7\xb7U\x06\xa3\xd7\xdcK\x12\x8f\x16_\xc8L\xfaw\xe4\\^\xb2%\x17'`\xf1\x8f\x04\xab\xe9K\xdf\xfd\xf0p\xc8l\xffRQ6L\xd6\xe4\x10\x92\x82\x9b\x0f\x8e9ƳTc\x94X\x8c\xc5\xff\x7f\xe6\x14\xd9\xeb2\x1b\xf4\x92W\t\xef\xbe=\x95\x8e\xb8\xdd\xf02\xb4\x84\x7f\xff\xe7\xee\xbf\x01\x00\x00\xff\xff\xf8I\x957\xdd!\x00\x00"), } var CRDs = crds() diff --git a/design/volume-snapshot-data-movement/volume-snapshot-data-movement.md b/design/volume-snapshot-data-movement/volume-snapshot-data-movement.md index 105f7d096..d04a6d5b3 100644 --- a/design/volume-snapshot-data-movement/volume-snapshot-data-movement.md +++ b/design/volume-snapshot-data-movement/volume-snapshot-data-movement.md @@ -691,7 +691,8 @@ type Provider interface { tags map[string]string, forceFull bool, parentSnapshot string, - volMode uploader.PersistentVolumeMode, + volMode uploader.PersistentVolumeMode, + uploaderCfg shared.UploaderConfig, updater uploader.ProgressUpdater) (string, bool, error) RunRestore( diff --git a/pkg/apis/velero/shared/uploader_config.go b/pkg/apis/velero/shared/uploader_config.go new file mode 100644 index 000000000..347b0cc1e --- /dev/null +++ b/pkg/apis/velero/shared/uploader_config.go @@ -0,0 +1,23 @@ +/* +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 shared + +// UploaderConfig defines the configuration for the uploader. +type UploaderConfig struct { + // ParallelFilesUpload is the number of files parallel uploads to perform when using the uploader. + ParallelFilesUpload int `json:"parallelFilesUpload,omitempty"` +} diff --git a/pkg/apis/velero/v1/backup_types.go b/pkg/apis/velero/v1/backup_types.go index ed1518010..628eda393 100644 --- a/pkg/apis/velero/v1/backup_types.go +++ b/pkg/apis/velero/v1/backup_types.go @@ -19,6 +19,8 @@ package v1 import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/vmware-tanzu/velero/pkg/apis/velero/shared" ) type Metadata struct { @@ -175,6 +177,11 @@ type BackupSpec struct { // If DataMover is "" or "velero", the built-in data mover will be used. // +optional DataMover string `json:"datamover,omitempty"` + + // UploaderConfig specifies the configuration for the uploader. + // +optional + // +nullable + UploaderConfig shared.UploaderConfig `json:"uploaderConfig,omitempty"` } // BackupHooks contains custom behaviors that should be executed at different phases of the backup. diff --git a/pkg/apis/velero/v1/pod_volume_backup_types.go b/pkg/apis/velero/v1/pod_volume_backup_types.go index 859617807..8b0d478ce 100644 --- a/pkg/apis/velero/v1/pod_volume_backup_types.go +++ b/pkg/apis/velero/v1/pod_volume_backup_types.go @@ -51,6 +51,9 @@ type PodVolumeBackupSpec struct { // volume backup as tags. // +optional Tags map[string]string `json:"tags,omitempty"` + + // UploaderConfig specifies the configuration for the uploader. + UploaderConfig shared.UploaderConfig `json:"uploaderConfig,omitempty"` } // PodVolumeBackupPhase represents the lifecycle phase of a PodVolumeBackup. diff --git a/pkg/apis/velero/v1/zz_generated.deepcopy.go b/pkg/apis/velero/v1/zz_generated.deepcopy.go index 5aa1b18ab..69d727806 100644 --- a/pkg/apis/velero/v1/zz_generated.deepcopy.go +++ b/pkg/apis/velero/v1/zz_generated.deepcopy.go @@ -381,6 +381,7 @@ func (in *BackupSpec) DeepCopyInto(out *BackupSpec) { *out = new(bool) **out = **in } + out.UploaderConfig = in.UploaderConfig } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackupSpec. @@ -951,6 +952,7 @@ func (in *PodVolumeBackupSpec) DeepCopyInto(out *PodVolumeBackupSpec) { (*out)[key] = val } } + out.UploaderConfig = in.UploaderConfig } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodVolumeBackupSpec. diff --git a/pkg/apis/velero/v2alpha1/data_upload_types.go b/pkg/apis/velero/v2alpha1/data_upload_types.go index 98f441064..4fb822ff4 100644 --- a/pkg/apis/velero/v2alpha1/data_upload_types.go +++ b/pkg/apis/velero/v2alpha1/data_upload_types.go @@ -60,6 +60,9 @@ type DataUploadSpec struct { // OperationTimeout specifies the time used to wait internal operations, // before returning error as timeout. OperationTimeout metav1.Duration `json:"operationTimeout"` + + // UploaderConfig specifies the configuration for the uploader. + UploaderConfig shared.UploaderConfig `json:"uploaderConfig,omitempty"` } type SnapshotType string diff --git a/pkg/apis/velero/v2alpha1/zz_generated.deepcopy.go b/pkg/apis/velero/v2alpha1/zz_generated.deepcopy.go index 9a9afaa6d..7b85568a6 100644 --- a/pkg/apis/velero/v2alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/velero/v2alpha1/zz_generated.deepcopy.go @@ -236,6 +236,7 @@ func (in *DataUploadSpec) DeepCopyInto(out *DataUploadSpec) { } } out.OperationTimeout = in.OperationTimeout + out.UploaderConfig = in.UploaderConfig } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DataUploadSpec. diff --git a/pkg/builder/backup_builder.go b/pkg/builder/backup_builder.go index b689bbcae..038e75350 100644 --- a/pkg/builder/backup_builder.go +++ b/pkg/builder/backup_builder.go @@ -300,6 +300,12 @@ func (b *BackupBuilder) DataMover(name string) *BackupBuilder { return b } +// ParallelFilesUpload sets the Backup's uploader parallel uploads +func (b *BackupBuilder) ParallelFilesUpload(parallel int) *BackupBuilder { + b.object.Spec.UploaderConfig.ParallelFilesUpload = parallel + return b +} + // WithStatus sets the Backup's status. func (b *BackupBuilder) WithStatus(status velerov1api.BackupStatus) *BackupBuilder { b.object.Status = status diff --git a/pkg/cmd/cli/backup/create.go b/pkg/cmd/cli/backup/create.go index 4925179dc..896f060c5 100644 --- a/pkg/cmd/cli/backup/create.go +++ b/pkg/cmd/cli/backup/create.go @@ -106,6 +106,7 @@ type CreateOptions struct { ItemOperationTimeout time.Duration ResPoliciesConfigmap string client kbclient.WithWatch + ParallelFilesUpload int } func NewCreateOptions() *CreateOptions { @@ -151,6 +152,7 @@ func (o *CreateOptions) BindFlags(flags *pflag.FlagSet) { flags.StringVar(&o.ResPoliciesConfigmap, "resource-policies-configmap", "", "Reference to the resource policies configmap that backup using") flags.StringVar(&o.DataMover, "data-mover", "", "Specify the data mover to be used by the backup. If the parameter is not set or set as 'velero', the built-in data mover will be used") + flags.IntVar(&o.ParallelFilesUpload, "parallel-files-upload", 0, "Number of files uploads simultaneously when running a backup. This is only applicable for the kopia uploader") } // BindWait binds the wait flag separately so it is not called by other create @@ -396,6 +398,9 @@ func (o *CreateOptions) BuildBackup(namespace string) (*velerov1api.Backup, erro if o.ResPoliciesConfigmap != "" { backupBuilder.ResourcePolicies(o.ResPoliciesConfigmap) } + if o.ParallelFilesUpload > 0 { + backupBuilder.ParallelFilesUpload(o.ParallelFilesUpload) + } } backup := backupBuilder.ObjectMeta(builder.WithLabelsMap(o.Labels.Data())).Result() diff --git a/pkg/cmd/cli/backup/create_test.go b/pkg/cmd/cli/backup/create_test.go index 4b88998d7..e115bbd19 100644 --- a/pkg/cmd/cli/backup/create_test.go +++ b/pkg/cmd/cli/backup/create_test.go @@ -185,7 +185,7 @@ func TestCreateCommand(t *testing.T) { defaultVolumesToFsBackup := "true" resPoliciesConfigmap := "cm-name-2" dataMover := "velero" - + parallelFilesUpload := 10 flags := new(flag.FlagSet) o := NewCreateOptions() o.BindFlags(flags) @@ -213,6 +213,7 @@ func TestCreateCommand(t *testing.T) { flags.Parse([]string{"--default-volumes-to-fs-backup", defaultVolumesToFsBackup}) flags.Parse([]string{"--resource-policies-configmap", resPoliciesConfigmap}) flags.Parse([]string{"--data-mover", dataMover}) + flags.Parse([]string{"--parallel-files-upload", fmt.Sprintf("%d", parallelFilesUpload)}) //flags.Parse([]string{"--wait"}) client := velerotest.NewFakeControllerRuntimeClient(t).(kbclient.WithWatch) @@ -261,6 +262,7 @@ func TestCreateCommand(t *testing.T) { require.Equal(t, defaultVolumesToFsBackup, o.DefaultVolumesToFsBackup.String()) require.Equal(t, resPoliciesConfigmap, o.ResPoliciesConfigmap) require.Equal(t, dataMover, o.DataMover) + require.Equal(t, parallelFilesUpload, o.ParallelFilesUpload) //assert.Equal(t, true, o.Wait) // verify oldAndNewFilterParametersUsedTogether diff --git a/pkg/cmd/util/output/backup_describer.go b/pkg/cmd/util/output/backup_describer.go index 039f9d653..b47d732d3 100644 --- a/pkg/cmd/util/output/backup_describer.go +++ b/pkg/cmd/util/output/backup_describer.go @@ -88,6 +88,11 @@ func DescribeBackup( DescribeResourcePolicies(d, backup.Spec.ResourcePolicy) } + if backup.Spec.UploaderConfig.ParallelFilesUpload > 0 { + d.Println() + DescribeUploaderConfig(d, backup.Spec) + } + status := backup.Status if len(status.ValidationErrors) > 0 { d.Println() @@ -123,13 +128,19 @@ func DescribeBackup( }) } -// DescribeResourcePolicies describes resource policiesin human-readable format +// DescribeResourcePolicies describes resource policies in human-readable format func DescribeResourcePolicies(d *Describer, resPolicies *v1.TypedLocalObjectReference) { d.Printf("Resource policies:\n") d.Printf("\tType:\t%s\n", resPolicies.Kind) d.Printf("\tName:\t%s\n", resPolicies.Name) } +// DescribeUploaderConfig describes uploader config in human-readable format +func DescribeUploaderConfig(d *Describer, spec velerov1api.BackupSpec) { + d.Printf("Uploader config:\n") + d.Printf("\tParallel files upload:\t%d\n", spec.UploaderConfig.ParallelFilesUpload) +} + // DescribeBackupSpec describes a backup spec in human-readable format. func DescribeBackupSpec(d *Describer, spec velerov1api.BackupSpec) { // TODO make a helper for this and use it in all the describers. diff --git a/pkg/cmd/util/output/backup_describer_test.go b/pkg/cmd/util/output/backup_describer_test.go index b0f78a917..6a55d4041 100644 --- a/pkg/cmd/util/output/backup_describer_test.go +++ b/pkg/cmd/util/output/backup_describer_test.go @@ -20,6 +20,22 @@ import ( velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" ) +func TestDescribeUploaderConfig(t *testing.T) { + input := builder.ForBackup("test-ns", "test-backup-1").ParallelFilesUpload(10).Result().Spec + d := &Describer{ + Prefix: "", + out: &tabwriter.Writer{}, + buf: &bytes.Buffer{}, + } + d.out.Init(d.buf, 0, 8, 2, ' ', 0) + DescribeUploaderConfig(d, input) + d.out.Flush() + expect := `Uploader config: + Parallel files upload: 10 +` + assert.Equal(t, expect, d.buf.String()) +} + func TestDescribeResourcePolicies(t *testing.T) { input := &v1.TypedLocalObjectReference{ Kind: "configmap", diff --git a/pkg/cmd/util/output/schedule_describe_test.go b/pkg/cmd/util/output/schedule_describe_test.go index 7123199ec..ad4cde9ed 100644 --- a/pkg/cmd/util/output/schedule_describe_test.go +++ b/pkg/cmd/util/output/schedule_describe_test.go @@ -59,7 +59,7 @@ Last Backup: input2 := builder.ForSchedule("velero", "schedule-2"). Phase(velerov1api.SchedulePhaseEnabled). CronSchedule("0 0 * * *"). - Template(builder.ForBackup("velero", "backup-1").Result().Spec). + Template(builder.ForBackup("velero", "backup-1").ParallelFilesUpload(10).Result().Spec). LastBackupTime("2023-06-25 15:04:05").Result() expect2 := `Name: schedule-2 Namespace: velero @@ -68,6 +68,9 @@ Annotations: Phase: Enabled +Uploader config: + Parallel files upload: 10 + Paused: false Schedule: 0 0 * * * diff --git a/pkg/cmd/util/output/schedule_describer.go b/pkg/cmd/util/output/schedule_describer.go index 57bd1726d..d02680206 100644 --- a/pkg/cmd/util/output/schedule_describer.go +++ b/pkg/cmd/util/output/schedule_describer.go @@ -48,6 +48,11 @@ func DescribeSchedule(schedule *v1.Schedule) string { DescribeResourcePolicies(d, schedule.Spec.Template.ResourcePolicy) } + if schedule.Spec.Template.UploaderConfig.ParallelFilesUpload > 0 { + d.Println() + DescribeUploaderConfig(d, schedule.Spec.Template) + } + status := schedule.Status if len(status.ValidationErrors) > 0 { d.Println() diff --git a/pkg/controller/data_upload_controller.go b/pkg/controller/data_upload_controller.go index 9465528e3..feb1e9866 100644 --- a/pkg/controller/data_upload_controller.go +++ b/pkg/controller/data_upload_controller.go @@ -344,7 +344,7 @@ func (r *DataUploadReconciler) runCancelableDataUpload(ctx context.Context, fsBa tags := map[string]string{ velerov1api.AsyncOperationIDLabel: du.Labels[velerov1api.AsyncOperationIDLabel], } - if err := fsBackup.StartBackup(path, fmt.Sprintf("%s/%s", du.Spec.SourceNamespace, du.Spec.SourcePVC), "", false, tags); err != nil { + if err := fsBackup.StartBackup(path, fmt.Sprintf("%s/%s", du.Spec.SourceNamespace, du.Spec.SourcePVC), "", false, tags, du.Spec.UploaderConfig); err != nil { return r.errorOut(ctx, du, err, "error starting data path backup", log) } diff --git a/pkg/controller/data_upload_controller_test.go b/pkg/controller/data_upload_controller_test.go index b61cd07b3..fd35cfe7d 100644 --- a/pkg/controller/data_upload_controller_test.go +++ b/pkg/controller/data_upload_controller_test.go @@ -45,6 +45,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" "github.com/vmware-tanzu/velero/internal/credentials" + "github.com/vmware-tanzu/velero/pkg/apis/velero/shared" velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" velerov2alpha1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v2alpha1" "github.com/vmware-tanzu/velero/pkg/builder" @@ -283,7 +284,7 @@ func (f *fakeDataUploadFSBR) Init(ctx context.Context, bslName string, sourceNam return nil } -func (f *fakeDataUploadFSBR) StartBackup(source datapath.AccessPoint, realSource string, parentSnapshot string, forceFull bool, tags map[string]string) error { +func (f *fakeDataUploadFSBR) StartBackup(source datapath.AccessPoint, realSource string, parentSnapshot string, forceFull bool, tags map[string]string, uploaderConfigs shared.UploaderConfig) error { du := f.du original := f.du.DeepCopy() du.Status.Phase = velerov2alpha1api.DataUploadPhaseCompleted diff --git a/pkg/controller/pod_volume_backup_controller.go b/pkg/controller/pod_volume_backup_controller.go index 6a66f98e1..cebe777c1 100644 --- a/pkg/controller/pod_volume_backup_controller.go +++ b/pkg/controller/pod_volume_backup_controller.go @@ -178,7 +178,7 @@ func (r *PodVolumeBackupReconciler) Reconcile(ctx context.Context, req ctrl.Requ } } - if err := fsBackup.StartBackup(path, "", parentSnapshotID, false, pvb.Spec.Tags); err != nil { + if err := fsBackup.StartBackup(path, "", parentSnapshotID, false, pvb.Spec.Tags, pvb.Spec.UploaderConfig); err != nil { return r.errorOut(ctx, &pvb, err, "error starting data path backup", log) } diff --git a/pkg/controller/pod_volume_backup_controller_test.go b/pkg/controller/pod_volume_backup_controller_test.go index 25fcae80a..8e0a5dcf9 100644 --- a/pkg/controller/pod_volume_backup_controller_test.go +++ b/pkg/controller/pod_volume_backup_controller_test.go @@ -37,6 +37,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/fake" "github.com/vmware-tanzu/velero/internal/credentials" + "github.com/vmware-tanzu/velero/pkg/apis/velero/shared" velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" "github.com/vmware-tanzu/velero/pkg/builder" "github.com/vmware-tanzu/velero/pkg/datapath" @@ -103,7 +104,7 @@ func (b *fakeFSBR) Init(ctx context.Context, bslName string, sourceNamespace str return nil } -func (b *fakeFSBR) StartBackup(source datapath.AccessPoint, realSource string, parentSnapshot string, forceFull bool, tags map[string]string) error { +func (b *fakeFSBR) StartBackup(source datapath.AccessPoint, realSource string, parentSnapshot string, forceFull bool, tags map[string]string, uploaderConfigs shared.UploaderConfig) error { pvb := b.pvb original := b.pvb.DeepCopy() diff --git a/pkg/datapath/file_system.go b/pkg/datapath/file_system.go index fba9eac7b..fcbc220c4 100644 --- a/pkg/datapath/file_system.go +++ b/pkg/datapath/file_system.go @@ -24,6 +24,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "github.com/vmware-tanzu/velero/internal/credentials" + "github.com/vmware-tanzu/velero/pkg/apis/velero/shared" velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" "github.com/vmware-tanzu/velero/pkg/repository" repokey "github.com/vmware-tanzu/velero/pkg/repository/keys" @@ -129,14 +130,14 @@ func (fs *fileSystemBR) Close(ctx context.Context) { fs.log.WithField("user", fs.jobName).Info("FileSystemBR is closed") } -func (fs *fileSystemBR) StartBackup(source AccessPoint, realSource string, parentSnapshot string, forceFull bool, tags map[string]string) error { +func (fs *fileSystemBR) StartBackup(source AccessPoint, realSource string, parentSnapshot string, forceFull bool, tags map[string]string, uploaderConfigs shared.UploaderConfig) error { if !fs.initialized { return errors.New("file system data path is not initialized") } go func() { snapshotID, emptySnapshot, err := fs.uploaderProv.RunBackup(fs.ctx, source.ByPath, realSource, tags, forceFull, - parentSnapshot, source.VolMode, fs) + parentSnapshot, source.VolMode, uploaderConfigs, fs) if err == provider.ErrorCanceled { fs.callbacks.OnCancelled(context.Background(), fs.namespace, fs.jobName) diff --git a/pkg/datapath/file_system_test.go b/pkg/datapath/file_system_test.go index c8e4b881c..eb3ad7a23 100644 --- a/pkg/datapath/file_system_test.go +++ b/pkg/datapath/file_system_test.go @@ -25,6 +25,7 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/vmware-tanzu/velero/pkg/apis/velero/shared" velerotest "github.com/vmware-tanzu/velero/pkg/test" "github.com/vmware-tanzu/velero/pkg/uploader/provider" providerMock "github.com/vmware-tanzu/velero/pkg/uploader/provider/mocks" @@ -95,12 +96,12 @@ func TestAsyncBackup(t *testing.T) { t.Run(test.name, func(t *testing.T) { fs := newFileSystemBR("job-1", "test", nil, "velero", Callbacks{}, velerotest.NewLogger()).(*fileSystemBR) mockProvider := providerMock.NewProvider(t) - mockProvider.On("RunBackup", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(test.result.Backup.SnapshotID, test.result.Backup.EmptySnapshot, test.err) + mockProvider.On("RunBackup", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(test.result.Backup.SnapshotID, test.result.Backup.EmptySnapshot, test.err) fs.uploaderProv = mockProvider fs.initialized = true fs.callbacks = test.callbacks - err := fs.StartBackup(AccessPoint{ByPath: test.path}, "", "", false, nil) + err := fs.StartBackup(AccessPoint{ByPath: test.path}, "", "", false, nil, shared.UploaderConfig{}) require.Equal(t, nil, err) <-finish diff --git a/pkg/datapath/mocks/types.go b/pkg/datapath/mocks/types.go index ecf655df0..6096523ce 100644 --- a/pkg/datapath/mocks/types.go +++ b/pkg/datapath/mocks/types.go @@ -11,6 +11,8 @@ import ( mock "github.com/stretchr/testify/mock" repository "github.com/vmware-tanzu/velero/pkg/repository" + + shared "github.com/vmware-tanzu/velero/pkg/apis/velero/shared" ) // AsyncBR is an autogenerated mock type for the AsyncBR type @@ -42,13 +44,13 @@ func (_m *AsyncBR) Init(ctx context.Context, bslName string, sourceNamespace str return r0 } -// StartBackup provides a mock function with given fields: source, realSource, parentSnapshot, forceFull, tags -func (_m *AsyncBR) StartBackup(source datapath.AccessPoint, realSource string, parentSnapshot string, forceFull bool, tags map[string]string) error { - ret := _m.Called(source, realSource, parentSnapshot, forceFull, tags) +// StartBackup provides a mock function with given fields: source, realSource, parentSnapshot, forceFull, tags, uploaderConfig +func (_m *AsyncBR) StartBackup(source datapath.AccessPoint, realSource string, parentSnapshot string, forceFull bool, tags map[string]string, uploaderConfig shared.UploaderConfig) error { + ret := _m.Called(source, realSource, parentSnapshot, forceFull, tags, uploaderConfig) var r0 error - if rf, ok := ret.Get(0).(func(datapath.AccessPoint, string, string, bool, map[string]string) error); ok { - r0 = rf(source, realSource, parentSnapshot, forceFull, tags) + if rf, ok := ret.Get(0).(func(datapath.AccessPoint, string, string, bool, map[string]string, shared.UploaderConfig) error); ok { + r0 = rf(source, realSource, parentSnapshot, forceFull, tags, uploaderConfig) } else { r0 = ret.Error(0) } diff --git a/pkg/datapath/types.go b/pkg/datapath/types.go index e26cf9482..9530538d9 100644 --- a/pkg/datapath/types.go +++ b/pkg/datapath/types.go @@ -20,6 +20,7 @@ import ( "context" "github.com/vmware-tanzu/velero/internal/credentials" + "github.com/vmware-tanzu/velero/pkg/apis/velero/shared" "github.com/vmware-tanzu/velero/pkg/repository" "github.com/vmware-tanzu/velero/pkg/uploader" ) @@ -62,7 +63,7 @@ type AsyncBR interface { Init(ctx context.Context, bslName string, sourceNamespace string, uploaderType string, repositoryType string, repoIdentifier string, repositoryEnsurer *repository.Ensurer, credentialGetter *credentials.CredentialGetter) error // StartBackup starts an asynchronous data path instance for backup - StartBackup(source AccessPoint, realSource string, parentSnapshot string, forceFull bool, tags map[string]string) error + StartBackup(source AccessPoint, realSource string, parentSnapshot string, forceFull bool, tags map[string]string, uploaderConfig shared.UploaderConfig) error // StartRestore starts an asynchronous data path instance for restore StartRestore(snapshotID string, target AccessPoint) error diff --git a/pkg/podvolume/backupper.go b/pkg/podvolume/backupper.go index 84be78a0f..3239f10f2 100644 --- a/pkg/podvolume/backupper.go +++ b/pkg/podvolume/backupper.go @@ -392,6 +392,7 @@ func newPodVolumeBackup(backup *velerov1api.Backup, pod *corev1api.Pod, volume c BackupStorageLocation: backup.Spec.StorageLocation, RepoIdentifier: repoIdentifier, UploaderType: uploaderType, + UploaderConfig: backup.Spec.UploaderConfig, }, } diff --git a/pkg/uploader/kopia/snapshot.go b/pkg/uploader/kopia/snapshot.go index d87404a36..a34a1e553 100644 --- a/pkg/uploader/kopia/snapshot.go +++ b/pkg/uploader/kopia/snapshot.go @@ -28,10 +28,6 @@ import ( "github.com/sirupsen/logrus" - "github.com/vmware-tanzu/velero/pkg/kopia" - "github.com/vmware-tanzu/velero/pkg/repository/udmrepo" - "github.com/vmware-tanzu/velero/pkg/uploader" - "github.com/kopia/kopia/fs" "github.com/kopia/kopia/fs/localfs" "github.com/kopia/kopia/repo" @@ -41,6 +37,11 @@ import ( "github.com/kopia/kopia/snapshot/restore" "github.com/kopia/kopia/snapshot/snapshotfs" "github.com/pkg/errors" + + "github.com/vmware-tanzu/velero/pkg/apis/velero/shared" + "github.com/vmware-tanzu/velero/pkg/kopia" + "github.com/vmware-tanzu/velero/pkg/repository/udmrepo" + "github.com/vmware-tanzu/velero/pkg/uploader" ) // All function mainly used to make testing more convenient @@ -104,9 +105,14 @@ func getDefaultPolicy() *policy.Policy { } } -func setupDefaultPolicy(ctx context.Context, rep repo.RepositoryWriter, sourceInfo snapshot.SourceInfo) (*policy.Tree, error) { +func setupPolicy(ctx context.Context, rep repo.RepositoryWriter, sourceInfo snapshot.SourceInfo, uploaderCfg shared.UploaderConfig) (*policy.Tree, error) { // some internal operations from Kopia code retrieves policies from repo directly, so we need to persist the policy to repo - err := setPolicyFunc(ctx, rep, sourceInfo, getDefaultPolicy()) + curPolicy := getDefaultPolicy() + if uploaderCfg.ParallelFilesUpload > 0 { + curPolicy.UploadPolicy.MaxParallelFileReads = newOptionalInt(uploaderCfg.ParallelFilesUpload) + } + + err := setPolicyFunc(ctx, rep, sourceInfo, curPolicy) if err != nil { return nil, errors.Wrap(err, "error to set policy") } @@ -127,7 +133,7 @@ func setupDefaultPolicy(ctx context.Context, rep repo.RepositoryWriter, sourceIn // Backup backup specific sourcePath and update progress func Backup(ctx context.Context, fsUploader SnapshotUploader, repoWriter repo.RepositoryWriter, sourcePath string, realSource string, - forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, tags map[string]string, log logrus.FieldLogger) (*uploader.SnapshotInfo, bool, error) { + forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, uploaderCfg shared.UploaderConfig, tags map[string]string, log logrus.FieldLogger) (*uploader.SnapshotInfo, bool, error) { if fsUploader == nil { return nil, false, errors.New("get empty kopia uploader") } @@ -172,7 +178,7 @@ func Backup(ctx context.Context, fsUploader SnapshotUploader, repoWriter repo.Re } kopiaCtx := kopia.SetupKopiaLog(ctx, log) - snapID, snapshotSize, err := SnapshotSource(kopiaCtx, repoWriter, fsUploader, sourceInfo, sourceEntry, forceFull, parentSnapshot, tags, log, "Kopia Uploader") + snapID, snapshotSize, err := SnapshotSource(kopiaCtx, repoWriter, fsUploader, sourceInfo, sourceEntry, forceFull, parentSnapshot, tags, uploaderCfg, log, "Kopia Uploader") if err != nil { return nil, false, err } @@ -223,6 +229,7 @@ func SnapshotSource( forceFull bool, parentSnapshot string, snapshotTags map[string]string, + uploaderCfg shared.UploaderConfig, log logrus.FieldLogger, description string, ) (string, int64, error) { @@ -258,7 +265,7 @@ func SnapshotSource( log.Infof("Using parent snapshot %s, start time %v, end time %v, description %s", previous[i].ID, previous[i].StartTime.ToTime(), previous[i].EndTime.ToTime(), previous[i].Description) } - policyTree, err := setupDefaultPolicy(ctx, rep, sourceInfo) + policyTree, err := setupPolicy(ctx, rep, sourceInfo, uploaderCfg) if err != nil { return "", 0, errors.Wrapf(err, "unable to set policy for si %v", sourceInfo) } diff --git a/pkg/uploader/kopia/snapshot_test.go b/pkg/uploader/kopia/snapshot_test.go index 34bc530b2..645434942 100644 --- a/pkg/uploader/kopia/snapshot_test.go +++ b/pkg/uploader/kopia/snapshot_test.go @@ -35,6 +35,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" + "github.com/vmware-tanzu/velero/pkg/apis/velero/shared" repomocks "github.com/vmware-tanzu/velero/pkg/repository/mocks" "github.com/vmware-tanzu/velero/pkg/uploader" uploadermocks "github.com/vmware-tanzu/velero/pkg/uploader/mocks" @@ -94,9 +95,10 @@ func TestSnapshotSource(t *testing.T) { } testCases := []struct { - name string - args []mockArgs - notError bool + name string + args []mockArgs + uploaderCfg shared.UploaderConfig + notError bool }{ { name: "regular test", @@ -150,6 +152,20 @@ func TestSnapshotSource(t *testing.T) { }, notError: false, }, + { + name: "set policy with ParallelFilesUpload", + args: []mockArgs{ + {methodName: "LoadSnapshot", returns: []interface{}{manifest, nil}}, + {methodName: "SaveSnapshot", returns: []interface{}{manifest.ID, nil}}, + {methodName: "TreeForSource", returns: []interface{}{nil, nil}}, + {methodName: "ApplyRetentionPolicy", returns: []interface{}{nil, nil}}, + {methodName: "SetPolicy", returns: []interface{}{nil}}, + {methodName: "Upload", returns: []interface{}{manifest, nil}}, + {methodName: "Flush", returns: []interface{}{nil}}, + }, + uploaderCfg: shared.UploaderConfig{ParallelFilesUpload: 10}, + notError: true, + }, { name: "failed to upload snapshot", args: []mockArgs{ @@ -182,7 +198,7 @@ func TestSnapshotSource(t *testing.T) { t.Run(tc.name, func(t *testing.T) { s := injectSnapshotFuncs() MockFuncs(s, tc.args) - _, _, err = SnapshotSource(ctx, s.repoWriterMock, s.uploderMock, sourceInfo, rootDir, false, "/", nil, log, "TestSnapshotSource") + _, _, err = SnapshotSource(ctx, s.repoWriterMock, s.uploderMock, sourceInfo, rootDir, false, "/", nil, tc.uploaderCfg, log, "TestSnapshotSource") if tc.notError { assert.NoError(t, err) } else { @@ -630,9 +646,9 @@ func TestBackup(t *testing.T) { var snapshotInfo *uploader.SnapshotInfo var err error if tc.isEmptyUploader { - snapshotInfo, isSnapshotEmpty, err = Backup(context.Background(), nil, s.repoWriterMock, tc.sourcePath, "", tc.forceFull, tc.parentSnapshot, tc.volMode, tc.tags, &logrus.Logger{}) + snapshotInfo, isSnapshotEmpty, err = Backup(context.Background(), nil, s.repoWriterMock, tc.sourcePath, "", tc.forceFull, tc.parentSnapshot, tc.volMode, shared.UploaderConfig{}, tc.tags, &logrus.Logger{}) } else { - snapshotInfo, isSnapshotEmpty, err = Backup(context.Background(), s.uploderMock, s.repoWriterMock, tc.sourcePath, "", tc.forceFull, tc.parentSnapshot, tc.volMode, tc.tags, &logrus.Logger{}) + snapshotInfo, isSnapshotEmpty, err = Backup(context.Background(), s.uploderMock, s.repoWriterMock, tc.sourcePath, "", tc.forceFull, tc.parentSnapshot, tc.volMode, shared.UploaderConfig{}, tc.tags, &logrus.Logger{}) } // Check if the returned error matches the expected error if tc.expectedError != nil { diff --git a/pkg/uploader/provider/kopia.go b/pkg/uploader/provider/kopia.go index 706393362..1ae69d21e 100644 --- a/pkg/uploader/provider/kopia.go +++ b/pkg/uploader/provider/kopia.go @@ -30,6 +30,7 @@ import ( "github.com/vmware-tanzu/velero/pkg/uploader/kopia" "github.com/vmware-tanzu/velero/internal/credentials" + "github.com/vmware-tanzu/velero/pkg/apis/velero/shared" velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" repokeys "github.com/vmware-tanzu/velero/pkg/repository/keys" "github.com/vmware-tanzu/velero/pkg/repository/udmrepo" @@ -119,6 +120,7 @@ func (kp *kopiaProvider) RunBackup( forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, + uploaderCfg shared.UploaderConfig, updater uploader.ProgressUpdater) (string, bool, error) { if updater == nil { return "", false, errors.New("Need to initial backup progress updater first") @@ -158,7 +160,7 @@ func (kp *kopiaProvider) RunBackup( realSource = fmt.Sprintf("%s/%s/%s", kp.requestorType, uploader.KopiaType, realSource) } - snapshotInfo, isSnapshotEmpty, err := BackupFunc(ctx, kpUploader, repoWriter, path, realSource, forceFull, parentSnapshot, volMode, tags, log) + snapshotInfo, isSnapshotEmpty, err := BackupFunc(ctx, kpUploader, repoWriter, path, realSource, forceFull, parentSnapshot, volMode, uploaderCfg, tags, log) if err != nil { if kpUploader.IsCanceled() { log.Error("Kopia backup is canceled") diff --git a/pkg/uploader/provider/kopia_test.go b/pkg/uploader/provider/kopia_test.go index e9c4fb7ef..c1fc95724 100644 --- a/pkg/uploader/provider/kopia_test.go +++ b/pkg/uploader/provider/kopia_test.go @@ -34,6 +34,7 @@ import ( "github.com/vmware-tanzu/velero/internal/credentials" "github.com/vmware-tanzu/velero/internal/credentials/mocks" + "github.com/vmware-tanzu/velero/pkg/apis/velero/shared" velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" "github.com/vmware-tanzu/velero/pkg/repository" udmrepo "github.com/vmware-tanzu/velero/pkg/repository/udmrepo" @@ -68,34 +69,34 @@ func TestRunBackup(t *testing.T) { testCases := []struct { name string - hookBackupFunc func(ctx context.Context, fsUploader kopia.SnapshotUploader, repoWriter repo.RepositoryWriter, sourcePath string, realSource string, forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, tags map[string]string, log logrus.FieldLogger) (*uploader.SnapshotInfo, bool, error) + hookBackupFunc func(ctx context.Context, fsUploader kopia.SnapshotUploader, repoWriter repo.RepositoryWriter, sourcePath string, realSource string, forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, uploaderCfg shared.UploaderConfig, tags map[string]string, log logrus.FieldLogger) (*uploader.SnapshotInfo, bool, error) volMode uploader.PersistentVolumeMode notError bool }{ { name: "success to backup", - hookBackupFunc: func(ctx context.Context, fsUploader kopia.SnapshotUploader, repoWriter repo.RepositoryWriter, sourcePath string, realSource string, forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, tags map[string]string, log logrus.FieldLogger) (*uploader.SnapshotInfo, bool, error) { + hookBackupFunc: func(ctx context.Context, fsUploader kopia.SnapshotUploader, repoWriter repo.RepositoryWriter, sourcePath string, realSource string, forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, uploaderCfg shared.UploaderConfig, tags map[string]string, log logrus.FieldLogger) (*uploader.SnapshotInfo, bool, error) { return &uploader.SnapshotInfo{}, false, nil }, notError: true, }, { name: "get error to backup", - hookBackupFunc: func(ctx context.Context, fsUploader kopia.SnapshotUploader, repoWriter repo.RepositoryWriter, sourcePath string, realSource string, forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, tags map[string]string, log logrus.FieldLogger) (*uploader.SnapshotInfo, bool, error) { + hookBackupFunc: func(ctx context.Context, fsUploader kopia.SnapshotUploader, repoWriter repo.RepositoryWriter, sourcePath string, realSource string, forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, uploaderCfg shared.UploaderConfig, tags map[string]string, log logrus.FieldLogger) (*uploader.SnapshotInfo, bool, error) { return &uploader.SnapshotInfo{}, false, errors.New("failed to backup") }, notError: false, }, { name: "got empty snapshot", - hookBackupFunc: func(ctx context.Context, fsUploader kopia.SnapshotUploader, repoWriter repo.RepositoryWriter, sourcePath string, realSource string, forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, tags map[string]string, log logrus.FieldLogger) (*uploader.SnapshotInfo, bool, error) { + hookBackupFunc: func(ctx context.Context, fsUploader kopia.SnapshotUploader, repoWriter repo.RepositoryWriter, sourcePath string, realSource string, forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, uploaderCfg shared.UploaderConfig, tags map[string]string, log logrus.FieldLogger) (*uploader.SnapshotInfo, bool, error) { return nil, true, errors.New("snapshot is empty") }, notError: false, }, { name: "success to backup block mode volume", - hookBackupFunc: func(ctx context.Context, fsUploader kopia.SnapshotUploader, repoWriter repo.RepositoryWriter, sourcePath string, realSource string, forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, tags map[string]string, log logrus.FieldLogger) (*uploader.SnapshotInfo, bool, error) { + hookBackupFunc: func(ctx context.Context, fsUploader kopia.SnapshotUploader, repoWriter repo.RepositoryWriter, sourcePath string, realSource string, forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, uploaderCfg shared.UploaderConfig, tags map[string]string, log logrus.FieldLogger) (*uploader.SnapshotInfo, bool, error) { return &uploader.SnapshotInfo{}, false, nil }, volMode: uploader.PersistentVolumeBlock, @@ -108,7 +109,7 @@ func TestRunBackup(t *testing.T) { tc.volMode = uploader.PersistentVolumeFilesystem } BackupFunc = tc.hookBackupFunc - _, _, err := kp.RunBackup(context.Background(), "var", "", nil, false, "", tc.volMode, &updater) + _, _, err := kp.RunBackup(context.Background(), "var", "", nil, false, "", tc.volMode, shared.UploaderConfig{}, &updater) if tc.notError { assert.NoError(t, err) } else { diff --git a/pkg/uploader/provider/mocks/Provider.go b/pkg/uploader/provider/mocks/Provider.go index a15bd940f..54ba8ac95 100644 --- a/pkg/uploader/provider/mocks/Provider.go +++ b/pkg/uploader/provider/mocks/Provider.go @@ -7,6 +7,8 @@ import ( mock "github.com/stretchr/testify/mock" + shared "github.com/vmware-tanzu/velero/pkg/apis/velero/shared" + uploader "github.com/vmware-tanzu/velero/pkg/uploader" ) @@ -29,30 +31,30 @@ func (_m *Provider) Close(ctx context.Context) error { return r0 } -// RunBackup provides a mock function with given fields: ctx, path, realSource, tags, forceFull, parentSnapshot, updater -func (_m *Provider) RunBackup(ctx context.Context, path string, realSource string, tags map[string]string, forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, updater uploader.ProgressUpdater) (string, bool, error) { - ret := _m.Called(ctx, path, realSource, tags, forceFull, parentSnapshot, volMode, updater) +// RunBackup provides a mock function with given fields: ctx, path, realSource, tags, forceFull, parentSnapshot, volMode, uploaderCfg, updater +func (_m *Provider) RunBackup(ctx context.Context, path string, realSource string, tags map[string]string, forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, uploaderCfg shared.UploaderConfig, updater uploader.ProgressUpdater) (string, bool, error) { + ret := _m.Called(ctx, path, realSource, tags, forceFull, parentSnapshot, volMode, uploaderCfg, updater) var r0 string var r1 bool var r2 error - if rf, ok := ret.Get(0).(func(context.Context, string, string, map[string]string, bool, string, uploader.ProgressUpdater) (string, bool, error)); ok { - return rf(ctx, path, realSource, tags, forceFull, parentSnapshot, updater) + if rf, ok := ret.Get(0).(func(context.Context, string, string, map[string]string, bool, string, uploader.PersistentVolumeMode, shared.UploaderConfig, uploader.ProgressUpdater) (string, bool, error)); ok { + return rf(ctx, path, realSource, tags, forceFull, parentSnapshot, volMode, uploaderCfg, updater) } - if rf, ok := ret.Get(0).(func(context.Context, string, string, map[string]string, bool, string, uploader.ProgressUpdater) string); ok { - r0 = rf(ctx, path, realSource, tags, forceFull, parentSnapshot, updater) + if rf, ok := ret.Get(0).(func(context.Context, string, string, map[string]string, bool, string, uploader.PersistentVolumeMode, shared.UploaderConfig, uploader.ProgressUpdater) string); ok { + r0 = rf(ctx, path, realSource, tags, forceFull, parentSnapshot, volMode, uploaderCfg, updater) } else { r0 = ret.Get(0).(string) } - if rf, ok := ret.Get(1).(func(context.Context, string, string, map[string]string, bool, string, uploader.ProgressUpdater) bool); ok { - r1 = rf(ctx, path, realSource, tags, forceFull, parentSnapshot, updater) + if rf, ok := ret.Get(1).(func(context.Context, string, string, map[string]string, bool, string, uploader.PersistentVolumeMode, shared.UploaderConfig, uploader.ProgressUpdater) bool); ok { + r1 = rf(ctx, path, realSource, tags, forceFull, parentSnapshot, volMode, uploaderCfg, updater) } else { r1 = ret.Get(1).(bool) } - if rf, ok := ret.Get(2).(func(context.Context, string, string, map[string]string, bool, string, uploader.ProgressUpdater) error); ok { - r2 = rf(ctx, path, realSource, tags, forceFull, parentSnapshot, updater) + if rf, ok := ret.Get(2).(func(context.Context, string, string, map[string]string, bool, string, uploader.PersistentVolumeMode, shared.UploaderConfig, uploader.ProgressUpdater) error); ok { + r2 = rf(ctx, path, realSource, tags, forceFull, parentSnapshot, volMode, uploaderCfg, updater) } else { r2 = ret.Error(2) } @@ -60,13 +62,13 @@ func (_m *Provider) RunBackup(ctx context.Context, path string, realSource strin return r0, r1, r2 } -// RunRestore provides a mock function with given fields: ctx, snapshotID, volumePath, updater +// RunRestore provides a mock function with given fields: ctx, snapshotID, volumePath, volMode, updater func (_m *Provider) RunRestore(ctx context.Context, snapshotID string, volumePath string, volMode uploader.PersistentVolumeMode, updater uploader.ProgressUpdater) error { ret := _m.Called(ctx, snapshotID, volumePath, volMode, updater) var r0 error - if rf, ok := ret.Get(0).(func(context.Context, string, string, uploader.ProgressUpdater) error); ok { - r0 = rf(ctx, snapshotID, volumePath, updater) + if rf, ok := ret.Get(0).(func(context.Context, string, string, uploader.PersistentVolumeMode, uploader.ProgressUpdater) error); ok { + r0 = rf(ctx, snapshotID, volumePath, volMode, updater) } else { r0 = ret.Error(0) } diff --git a/pkg/uploader/provider/provider.go b/pkg/uploader/provider/provider.go index 09ff3f162..5cffc4b32 100644 --- a/pkg/uploader/provider/provider.go +++ b/pkg/uploader/provider/provider.go @@ -28,6 +28,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "github.com/vmware-tanzu/velero/internal/credentials" + "github.com/vmware-tanzu/velero/pkg/apis/velero/shared" velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" "github.com/vmware-tanzu/velero/pkg/uploader" ) @@ -49,6 +50,7 @@ type Provider interface { forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, + uploaderCfg shared.UploaderConfig, updater uploader.ProgressUpdater) (string, bool, error) // RunRestore which will do restore for one specific volume with given snapshot id and return error // updater is used for updating backup progress which implement by third-party diff --git a/pkg/uploader/provider/restic.go b/pkg/uploader/provider/restic.go index 6c6cf5992..9c19782b9 100644 --- a/pkg/uploader/provider/restic.go +++ b/pkg/uploader/provider/restic.go @@ -27,6 +27,7 @@ import ( v1 "k8s.io/api/core/v1" "github.com/vmware-tanzu/velero/internal/credentials" + "github.com/vmware-tanzu/velero/pkg/apis/velero/shared" velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" "github.com/vmware-tanzu/velero/pkg/restic" "github.com/vmware-tanzu/velero/pkg/uploader" @@ -122,6 +123,7 @@ func (rp *resticProvider) RunBackup( forceFull bool, parentSnapshot string, volMode uploader.PersistentVolumeMode, + uploaderCfg shared.UploaderConfig, updater uploader.ProgressUpdater) (string, bool, error) { if updater == nil { return "", false, errors.New("Need to initial backup progress updater first") @@ -144,6 +146,10 @@ func (rp *resticProvider) RunBackup( "parentSnapshot": parentSnapshot, }) + if uploaderCfg.ParallelFilesUpload > 0 { + log.Warnf("ParallelFilesUpload is set to %d, but restic does not support parallel file uploads. Ignoring.", uploaderCfg.ParallelFilesUpload) + } + backupCmd := resticBackupCMDFunc(rp.repoIdentifier, rp.credentialsFile, path, tags) backupCmd.Env = rp.cmdEnv backupCmd.CACertFile = rp.caCertFile diff --git a/pkg/uploader/provider/restic_test.go b/pkg/uploader/provider/restic_test.go index 038657cf9..62f289968 100644 --- a/pkg/uploader/provider/restic_test.go +++ b/pkg/uploader/provider/restic_test.go @@ -31,6 +31,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/fake" "github.com/vmware-tanzu/velero/internal/credentials" + "github.com/vmware-tanzu/velero/pkg/apis/velero/shared" velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" "github.com/vmware-tanzu/velero/pkg/builder" "github.com/vmware-tanzu/velero/pkg/restic" @@ -149,9 +150,9 @@ func TestResticRunBackup(t *testing.T) { } if !tc.nilUpdater { updater := FakeBackupProgressUpdater{PodVolumeBackup: &velerov1api.PodVolumeBackup{}, Log: tc.rp.log, Ctx: context.Background(), Cli: fake.NewClientBuilder().WithScheme(util.VeleroScheme).Build()} - _, _, err = tc.rp.RunBackup(context.Background(), "var", "", map[string]string{}, false, parentSnapshot, tc.volMode, &updater) + _, _, err = tc.rp.RunBackup(context.Background(), "var", "", map[string]string{}, false, parentSnapshot, tc.volMode, shared.UploaderConfig{}, &updater) } else { - _, _, err = tc.rp.RunBackup(context.Background(), "var", "", map[string]string{}, false, parentSnapshot, tc.volMode, nil) + _, _, err = tc.rp.RunBackup(context.Background(), "var", "", map[string]string{}, false, parentSnapshot, tc.volMode, shared.UploaderConfig{}, nil) } tc.rp.log.Infof("test name %v error %v", tc.name, err)