# Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: squid3@treenet.co.nz-20081212080230-gij6p59hq8vt8rxg # target_branch: http://www.squid-cache.org/bzr/squid3/trunk/ # testament_sha1: c87051258a236743bbb35391cb03fdb06d9588f2 # timestamp: 2008-12-12 21:04:06 +1300 # source_branch: http://www.squid-cache.org/bzr/squid3/trunk/ # message: Polish for ZPH Patch. Creating single-line config # base_revision_id: squid3@treenet.co.nz-20081212001710-\ # 9bzmphranx0rn42x # # Begin patch === modified file 'configure.in' --- configure.in 2008-12-10 20:19:50 +0000 +++ configure.in 2008-12-12 01:11:43 +0000 @@ -3820,6 +3820,7 @@ src/adaptation/Makefile \ src/ICAP/Makefile \ src/icmp/Makefile \ + src/ip/Makefile \ src/eCAP/Makefile \ contrib/Makefile \ snmplib/Makefile \ === modified file 'src/Makefile.am' --- src/Makefile.am 2008-12-10 20:40:01 +0000 +++ src/Makefile.am 2008-12-12 01:11:43 +0000 @@ -34,7 +34,7 @@ TESTS=$(check_PROGRAMS) check_PROGRAMS= -SUBDIRS = fs repl auth icmp +SUBDIRS = fs repl auth icmp ip if USE_ADAPTATION SUBDIRS += adaptation @@ -243,7 +243,13 @@ @DISK_PROGRAMS@ \ $(UNLINKD) -cf_gen_SOURCES = cf_gen.cc defines.h debug.cc time.cc +cf_gen_SOURCES = \ + cf_gen.cc \ + defines.h \ + debug.cc \ + ip/stubQosConfig.cc \ + time.cc + nodist_cf_gen_SOURCES = globals.cc nodist_cf_gen_HEADER = cf_gen_defines.h cf_gen.$(OBJEXT): cf_gen_defines.h @@ -423,7 +429,6 @@ TextException.cc \ TextException.h - # authentication framework libauth_la_SOURCES = \ AuthConfig.cc \ @@ -684,6 +689,7 @@ libsquid.la \ libauth.la \ icmp/libicmp.la icmp/libicmp-core.la \ + ip/libip.la \ -L../lib \ @XTRA_OBJS@ \ @DISK_LINKOBJS@ \ @@ -864,6 +870,7 @@ peer_sourcehash.cc \ peer_userhash.cc \ protos.h \ + ip/stubQosConfig.cc \ redirect.cc \ referer.cc \ refresh.cc \ @@ -1210,6 +1217,7 @@ tests/stub_store.cc HttpHeaderTools.cc HttpHeader.cc acl.cc mem.cc \ MemBuf.cc HttpHdrContRange.cc Packer.cc ACLChecklist.cc HttpHdrCc.cc HttpHdrSc.cc \ HttpHdrScTarget.cc url.cc ACLProxyAuth.cc ACLRegexData.cc ACLUserData.cc \ + ip/stubQosConfig.cc \ StatHist.cc HttpHdrRange.cc ETag.cc tests/stub_errorpage.cc \ tests/stub_HttpRequest.cc tests/stub_DelayId.cc \ tests/stub_MemObject.cc mem_node.cc \ @@ -1286,6 +1294,7 @@ mem_node.cc \ Packer.cc \ Parsing.cc \ + ip/stubQosConfig.cc \ StatHist.cc \ stmem.cc \ String.cc \ @@ -1422,6 +1431,7 @@ peer_select.cc \ peer_sourcehash.cc \ peer_userhash.cc \ + ip/stubQosConfig.cc \ redirect.cc \ referer.cc \ refresh.cc \ @@ -1492,7 +1502,8 @@ tests/testDiskIO.cc \ tests/testDiskIO.h \ tests/testMain.cc \ - tests/stub_cache_manager.cc + tests/stub_cache_manager.cc \ + ip/stubQosConfig.cc nodist_tests_testDiskIO_SOURCES= \ $(SWAP_TEST_GEN_SOURCES) tests_testDiskIO_LDADD = \ @@ -1598,6 +1609,7 @@ peer_select.cc \ peer_sourcehash.cc \ peer_userhash.cc \ + ip/stubQosConfig.cc \ redirect.cc \ referer.cc \ refresh.cc \ @@ -1754,6 +1766,7 @@ peer_select.cc \ peer_sourcehash.cc \ peer_userhash.cc \ + ip/stubQosConfig.cc \ redirect.cc \ referer.cc \ refresh.cc \ @@ -1900,6 +1913,7 @@ peer_sourcehash.cc \ peer_userhash.cc \ pconn.cc \ + ip/stubQosConfig.cc \ redirect.cc \ referer.cc \ refresh.cc \ @@ -2061,6 +2075,7 @@ peer_select.cc \ peer_sourcehash.cc \ peer_userhash.cc \ + ip/stubQosConfig.cc \ redirect.cc \ referer.cc \ refresh.cc \ @@ -2159,6 +2174,7 @@ HttpHdrScTarget.cc url.cc ACLProxyAuth.cc ACLRegexData.cc ACLUserData.cc \ StatHist.cc HttpHdrRange.cc ETag.cc tests/stub_errorpage.cc \ tests/stub_HttpRequest.cc tests/stub_access_log.cc \ + ip/stubQosConfig.cc \ refresh.cc \ tests/stub_store_client.cc \ tests/stub_tools.cc \ @@ -2209,14 +2225,16 @@ @SQUID_CPPUNIT_LA@ # string needs mem.cc. +# libsquid pulls in SquidConfig and children. stub them. tests_testString_SOURCES = \ mem.cc \ + ip/stubQosConfig.cc \ String.cc \ tests/testMain.cc \ tests/testString.cc \ tests/testString.h \ tests/stub_cache_manager.cc \ - time.cc + time.cc nodist_tests_testString_SOURCES = \ $(TESTSOURCES) tests_testString_LDADD = \ @@ -2423,6 +2441,7 @@ peer_select.cc \ peer_sourcehash.cc \ peer_userhash.cc \ + ip/stubQosConfig.cc \ redirect.cc \ referer.cc \ refresh.cc \ === modified file 'src/cf.data.depend' --- src/cf.data.depend 2008-09-27 18:33:49 +0000 +++ src/cf.data.depend 2008-11-19 06:59:00 +0000 @@ -38,6 +38,7 @@ onoff peer peer_access cache_peer acl +QosConfig refreshpattern removalpolicy size_t === modified file 'src/cf.data.pre' --- src/cf.data.pre 2008-11-09 03:37:11 +0000 +++ src/cf.data.pre 2008-11-19 06:59:00 +0000 @@ -1226,8 +1226,8 @@ tcp_outgoing_tos 0x20 good_service_net TOS/DSCP values really only have local significance - so you should - know what you're specifying. For more information, see RFC2474 and - RFC3260. + know what you're specifying. For more information, see RFC2474, + RFC2475, and RFC3260. The TOS/DSCP byte must be exactly that - a octet value 0 - 255, or "default" to use whatever default your host has. Note that in @@ -1253,64 +1253,49 @@ making the request. DOC_END -NAME: zph_tos_local -TYPE: int -IFDEF: USE_ZPH_QOS -DEFAULT: 0 -LOC: Config.zph_tos_local -DOC_START - Allows you to select a TOS/Diffserv value to mark local hits. Read above - (tcp_outgoing_tos) for details/requirements about TOS. - Default: 0 (disabled). -DOC_END - -NAME: zph_tos_peer -TYPE: int -IFDEF: USE_ZPH_QOS -DEFAULT: 0 -LOC: Config.zph_tos_peer -DOC_START - Allows you to select a TOS/Diffserv value to mark peer hits. Read above - (tcp_outgoing_tos) for details/requirements about TOS. - Default: 0 (disabled). -DOC_END - -NAME: zph_tos_parent -COMMENT: on|off -TYPE: onoff -IFDEF: USE_ZPH_QOS -DEFAULT: on -LOC: Config.onoff.zph_tos_parent -DOC_START - Set this to off if you want only sibling hits to be marked. - If set to on (default), parent hits are being marked too. -DOC_END - -NAME: zph_preserve_miss_tos -COMMENT: on|off -TYPE: onoff -IFDEF: USE_ZPH_QOS -DEFAULT: on -LOC: Config.onoff.zph_preserve_miss_tos -DOC_START - If set to on (default), any HTTP response towards clients will - have the TOS value of the response comming from the remote - server masked with the value of zph_preserve_miss_tos_mask. - For this to work correctly, you will need to patch your linux - kernel with the TOS preserving ZPH patch. - The kernel patch can be downloaded from http://zph.bratcheda.org -DOC_END - -NAME: zph_preserve_miss_tos_mask -TYPE: int -IFDEF: USE_ZPH_QOS -DEFAULT: 255 -LOC: Config.zph_preserve_miss_tos_mask -DOC_START - Allows you to mask certain bits in the TOS received from the - remote server, before copying the value to the TOS send towards - clients. - Default: 255 (TOS from server is not changed). +NAME: qos_flows +TYPE: QosConfig +IFDEF: USE_ZPH_QOS +DEFAULT: none +LOC: Config.zph +DOC_START + Allows you to select a TOS/DSCP value to mark outgoing + connections with, based on where the reply was sourced. + + TOS values really only have local significance - so you should + know what you're specifying. For more information, see RFC2474, + RFC2475, and RFC3260. + + The TOS/DSCP byte must be exactly that - octet value 0x00-0xFF. + Note that in practice often only values up to 0x3F are usable + as the two highest bits have been redefined for use by ECN + (RFC3168). + + This setting is configured by setting the source TOS values: + + local-hit=0xFF Value to mark local cache hits. + + sibling-hit=0xFF Value to mark hits from sibling peers. + + parent-hit=0xFF Value to mark hits from parent peers. + + + For the following to work correctly, you will need to patch your + linux kernel with the TOS preserving ZPH patch. + The kernel patch can be downloaded from http://zph.bratcheda.org + + + disable-preserve-miss + If set, any HTTP response towards clients will + have the TOS value of the response comming from the + remote server masked with the value of miss-mask. + + miss-mask=0xFF + Allows you to mask certain bits in the TOS received from the + remote server, before copying the value to the TOS sent + towards clients. + Default: 0xFF (TOS from server is not changed). + DOC_END NAME: tcp_outgoing_address === modified file 'src/client_side_reply.cc' --- src/client_side_reply.cc 2008-10-10 08:02:53 +0000 +++ src/client_side_reply.cc 2008-11-19 06:59:00 +0000 @@ -1635,9 +1635,9 @@ assert(http->out.size == 0); assert(http->out.offset == 0); #if USE_ZPH_QOS - if (Config.zph_tos_local) { - debugs(33, 2, "ZPH Local hit, TOS="<getConn()->fd,Config.zph_tos_local); + if (Config.zph.tos_local_hit) { + debugs(33, 2, "ZPH Local hit, TOS=" << Config.zph.tos_local_hit); + comm_set_tos(http->getConn()->fd, Config.zph.tos_local_hit); } #endif /* USE_ZPH_QOS */ tempBuffer.offset = reqofs; @@ -1915,13 +1915,14 @@ if (reqofs==0 && !logTypeIsATcpHit(http->logType)) { assert(fd >= 0); // the beginning of this method implies fd may be -1 int tos = 0; - if (Config.zph_tos_peer && - (http->request->hier.code==SIBLING_HIT || - (Config.onoff.zph_tos_parent && http->request->hier.code==PARENT_HIT) ) ) { - tos = Config.zph_tos_peer; - debugs(33, 2, "ZPH: Peer hit with hier.code="<request->hier.code<<", TOS="<request->hier.code==SIBLING_HIT ) { + tos = Config.zph.tos_sibling_hit; + debugs(33, 2, "ZPH: Sibling Peer hit with hier.code=" << http->request->hier.code << ", TOS=" << tos); + } else if (Config.zph.tos_parent_hit && http->request->hier.code==PARENT_HIT) { + tos = Config.zph.tos_parent_hit; + debugs(33, 2, "ZPH: Parent Peer hit with hier.code=" << http->request->hier.code << ", TOS=" << tos); + } else if (Config.zph.preserve_miss_tos && Config.zph.preserve_miss_tos_mask) { + tos = fd_table[fd].upstreamTOS & Config.zph.preserve_miss_tos_mask; debugs(33, 2, "ZPH: Preserving TOS on miss, TOS="<0) { + storeAppendPrintf(entry, " local-hit=%2x", tos_local_hit); + } + + if (tos_sibling_hit >0) { + storeAppendPrintf(entry, " sibling-hit=%2x", tos_sibling_hit); + } + if (tos_parent_hit >0) { + storeAppendPrintf(entry, " parent-hit=%2x", tos_parent_hit); + } + if (preserve_miss_tos != 0) { + storeAppendPrintf(entry, " disable-preserve-miss"); + } + if (preserve_miss_tos && preserve_miss_tos_mask != 0) { + storeAppendPrintf(entry, " miss-mask=%2x", preserve_miss_tos_mask); + } + storeAppendPrintf(entry, "\n"); +} + +#endif /* USE_ZPH_QOS */ === added file 'src/ip/QosConfig.h' --- src/ip/QosConfig.h 1970-01-01 00:00:00 +0000 +++ src/ip/QosConfig.h 2008-11-19 06:59:00 +0000 @@ -0,0 +1,33 @@ +#ifndef SQUID_QOSCONFIG_H +#define SQUID_QOSCONFIG_H + +#include "config.h" + +#if USE_ZPH_QOS + +class StoreEntry; + +class QosConfig +{ +public: + int tos_local_hit; + int tos_sibling_hit; + int tos_parent_hit; + int preserve_miss_tos; + int preserve_miss_tos_mask; + +public: + QosConfig(); + ~QosConfig() {}; + + void parseConfigLine(); + void dumpConfigLine(StoreEntry *entry, const char *name) const; +}; + +/* legacy parser access wrappers */ +#define parse_QosConfig(X) (X)->parseConfigLine() +#define dump_QosConfig(e,n,X) (X).dumpConfigLine(e,n) +#define free_QosConfig(X) + +#endif /* USE_ZPH_QOS */ +#endif /* SQUID_QOSCONFIG_H */ === added file 'src/ip/stubQosConfig.cc' --- src/ip/stubQosConfig.cc 1970-01-01 00:00:00 +0000 +++ src/ip/stubQosConfig.cc 2008-11-19 06:59:00 +0000 @@ -0,0 +1,51 @@ +#include "squid.h" + +#if USE_ZPH_QOS + +#include "QosConfig.h" +#include "Store.h" + +QosConfig::QosConfig() : + tos_local_hit(0), + tos_sibling_hit(0), + tos_parent_hit(0), + preserve_miss_tos(1), + preserve_miss_tos_mask(255) +{ + ; +} + +void +QosConfig::parseConfigLine() +{ + // %i honors 0 and 0x prefixes, which are important for things like umask + /* parse options ... */ + char *token; + while( (token = strtok(NULL, w_space)) ) { + + if(strncmp(token, "local-hit=",10) == 0) { + sscanf(&token[10], "%i", &tos_local_hit); + } + else if(strncmp(token, "sibling-hit=",12) == 0) { + sscanf(&token[12], "%i", &tos_sibling_hit); + } + else if(strncmp(token, "parent-hit=",11) == 0) { + sscanf(&token[11], "%i", &tos_parent_hit); + } + else if(strcmp(token, "disable-preserve-miss") == 0) { + preserve_miss_tos = 0; + preserve_miss_tos_mask = 0; + } + else if(preserve_miss_tos && strncmp(token, "miss-mask=",10) == 0) { + sscanf(&token[10], "%i", &preserve_miss_tos_mask); + } + } +} + +void +QosConfig::dumpConfigLine(StoreEntry * entry, const char *name) const +{ + ; /* Not needed in stub */ +} + +#endif /* USE_ZPH_QOS */ === modified file 'src/structs.h' --- src/structs.h 2008-12-12 00:17:10 +0000 +++ src/structs.h 2008-12-12 08:02:30 +0000 @@ -124,6 +124,10 @@ #include "icmp/IcmpConfig.h" #endif +#if USE_ZPH_QOS +#include "QosConfig.h" +#endif + /* forward decl for SquidConfig, see RemovalPolicy.h */ class RemovalPolicySettings; @@ -443,10 +447,6 @@ int log_uses_indirect_client; #endif /* FOLLOW_X_FORWARDED_FOR */ -#if USE_ZPH_QOS - int zph_tos_parent; - int zph_preserve_miss_tos; -#endif int WIN32_IpAddrChangeMonitor; } onoff; @@ -592,11 +592,11 @@ int sleep_after_fork; /* microseconds */ time_t minimum_expiry_time; /* seconds */ external_acl *externalAclHelperList; + #if USE_ZPH_QOS - int zph_tos_local; - int zph_tos_peer; - int zph_preserve_miss_tos_mask; + QosConfig zph; #endif + #if USE_SSL struct { # Begin bundle IyBCYXphYXIgcmV2aXNpb24gYnVuZGxlIHY0CiMKQlpoOTFBWSZTWZ4yUwwAFsBfgERwf//////3 /36/////YCAenvfeXcd73u8B99Evsb33euoxW573sLdtXPro3vOHQe2DbGkg0GWjO+vkW6oM73vd jptut7se9k0Wnd23a9aKUds2x0NFOj1T1QBvb0fCSJNBNMk9NNDRMmk8U2k9Jpqn6Jp6NU/Ugepp 6mn6TUDQD8qYSSaATQEEynqNTKjT2U9U2aRpG9QjQYmmnqZGQ9RhPQNNNAiVJtqTepPUAAAAAA0A AABoABJpUTTJJqP0p+lPJqH6kAAafqj9UAGQaBkAAA0CJQgmgCNAnpNMhqejKYm0SnmqfqZqjT1M j0jyINANBJEE0JhDTRMJoExpEj2pqaD0mQANA0AAFygn9V74EHYRxJJIpKygyAMIrngh4Xf3/H5n 5ePdrXhTR8udjWSEjYJPFiE4l/Kf8pFQDRlGSIu9xEOqWlM7hgrf6fSgb2ebeRfTLozzD7Fynhg7 Ts43jw4HM9fkOOmXHPmux4+0G86k6BPBxaXmaMiWuBJgtJ7R70hWZCbYwCJ7Ha8Hq9U9/1ykuQ4H 6qHcwJxo9UB92VbQNhD+GWPEP6HYi3u5EjNmqIsTi8WWhIBr12LkuRkIQinN+3V2XnDTQ9c6+w2d csPJs8tS4mbR/pXzCGPkpehCEgwQsMQ/Z+Fepl10qjSFCLXRlPdoxgUses79GLd0e2r24WQPaD+Z BJeTFPNTclZuwsrVzbNrm7kNTK1OdDHLNAkNrnio3t2bZYRSgnUzWTmRMCtTkaoIb28PjAAJCiCC aGJE3sqZaSHmaFHN4cGbp3QcZZpJ41RGw24KjV0N6Lgo3t3BhvAtllQnDVeHIHA3ebh1lHuUE85+ FBQTMoJ2c2/ijVtdB9xrQ4MwhjBGksxHPTjGQUAdQfo1ufOMqz3/7LD04FsPSXqiF+s6ZUPhxwDc IXtEeOTALZFUFJFgQURVSKRVhrMwf5wOw0ePk/3ADZETw7e/1fXfqDWbJJKBIyMIwJYATS8sECVF qQvNTFLVyARt6IvJrJKrzoKtNcaqBoO7jMWjCZ5WOsyEjk1UXL1SUF2d2LGYeDSeafSlF6QkEDUW TFIyHIt3EOA9pwIKrK1LvimnsuaPUA1d68RjVgjgpUrQ4CGIWgxIcu6MqIraKdWk144DvLpF98Q6 mcOFt0zhY+ncmJskZOxl5sKdbRoWC8u+HUlCZYTTiigZMZiw0dalPOPG1HGabUpKjPf2G51R4Pad iCYZM3YmI5rsdG1ZvAz8Ikuz0DdJrxC3cYSfqqxdbz5SYbbNGfxj6ctEZBe/Irha6tj5+fNoQQK8 IXYjtjy5+w1MmufNm/F9Hg/EecW50t6ZBKhKlRNnHwZJo2v6nu30G/U7R+zrZw0ZJbl8YFIUo6/I 3R4q8Z3Pfqc8Ffces9h8bSMmEZw3hCBCwXdZXHy05smukxzU89yKb5IwG5YIM4mAz46Kfb8qFdRz QMVWepAWk8s9dm/NZVmH0ZH1YbroTvWX2IDMmGYYYYYZgtc1tyqWq3FP4Tvy8rVZbnoNvbrnE9WQ AQpoOqVdJRbHbdU/wmTtBdbhq3M9XM2bWZmjimVTUyPmzu9rTj+RkgUVUF+KS5mYliZLNwkZOkkA h2rj2dfHrGj7JLdFW7sbtr7Z3fDtRZ7RQE5UDqyWA9jso1rtMD7WfRJskJK6GTJhmtZxqiltzb2r bC1d1NzVMoQk4Qhb6bdIt5Q3nLtSmt+mMZZxvwVp8+yR5rp9ADlfIHkVXRq168+vcPtHEXOyDACQ IRSEkQRBCE9wnrishPIe3q+ERxpkCWBwdkMLzEwHxAYXqNZzgMsizu/QLOWDL5UBAfFqlGoiRjCt KqacQx4iJgOv6n2Wvu8nN59ftIFxoDabjGqiRFzCPCGWj8ZiUoGCTkxcX9wFs9U0Nc0VhQeUlvqT WQIr3HEB4p/0BN7OYTEDesdMC8fotnUSc1utJYRgBHIWHE6y9aIhJm6oMrSoZyT2oZFjYGJeHgN5 xnY17YMWg2MCFRXiYu9gBeQAPBDMbR69ha0oU6EKo1dSrFgcNWcKUDe7HpG7DEcR4I+JcbR3dne+ KRmjYFZsE4WWG4OQaNSskCs+mzGOvKaeG2H3VqN7rTmdFBUMsMco4VoRjcnuTMrux0kRYOaYMkgF EUOgvVZffhXStsrh9AwREw65Gb9qgOizHY4RfTippA7TI0J9n5FYfOwj3lrrVhx8jYouQhOO+bv2 w+cBRGFt6rRDuzOO7p3d3ehRtwUshXSRlLfpv4c2z0cG23EkyilL0PMyvEJhMWZsArDBJoxSqga0 OnS4sNTDYyYZ3JwtJWIhMkytKzLFzJmGPcUSHqijZMJKQXBGROViWV8C+MBJVJKcwVxihC0UVybP 3naeg2XmRhhj2lBuRhkhQuXRQOZUKYNSJQickKVLB1Ece8VEi1KhYUITu7ZDPQkaDkhMSuLYiQME I096R5FI1IQhi41F8P6ZE6Nok1BnzMAkOakSm3BQNjOCORYYaBUgUZJTBJKorrTS5kZljRrlsGSZ yCqEMixRAcDCr0BgiSP7hJWIWNj8hoYHJl5oLTXrMS8j76Ej1oWFYXHbbZtIrvTi4B8izD7wl/at EA2VWhwiB0U5Kmja1q4GrA57GBGFVMnpYZ6WEU1iGNtamtwdedwdFbsEoTXMd6pjv9AUCMVLgBC5 O6CBBhR3f5Co6LYapjdkStXLhnVoKmiiFhbiwl4bDJGvPeQFqEwhFZgROBaYBOOA6C9XzSC8HdLL TSiOG0qlkdC6qxMKBTz0qjDeRDbovLSfnOGkpxM5xj4rNs94i4IhscteIuwbRkIY5jGaQwODEzII GpI1JcCJOkjUqOMhMiDUuwILduCOCDAhAIJUIZ7DsLFUeXDtKiyIxgJ2Qr3METKth6iICKhMYRkw SGQ7uFfm9FR9bAZUcCjIiO6lJ+FhQuqSkzVFgQiAKYyumuNPugJl9hIgVOg5qZmxuOdSQ5yNzMNz BkbESRYJHMmWNCA5UubHtHQvcsJW5KY3Gm+1pVYxOXBsTm1q2lRq1JtCib0idgzVIbYgMnFyYoMQ xZmZm5h2DcCCXIqalTIZqwZIuIo4YWW2YMJgQQJVG1cKqVLUsShxEGl40NAaT5LhzSQuCSI4KUcF IVWJkULSQNZ3iuFXAUkoMsHU2SLxGOo2k6DljQgDsf8BFCg7E2DLI8zIw5EoJTZRPD9FTuXiUY8e gmdkDbE4kuzwXkQ5UbhIgHVRiMGZcikJxAXIGxUc9iX0hYscg5li5A5Hc/ii6DUsJhJX/UAt4zce KO46evyvk5HROTE9y1rkDzNu7KLlS6eY6oukWuPWFcYaLTUUJwWVbAWMgTruwGCs0vd5ELNFr2Fr aBj0wc+QYpKCR3mTKcB6k20c5M1zzIk9CWo2cjmtAnwZNFPzMGwyRuVC/M8iJHPWEtixqRL3pCpB 5jTlFTCxROSJRKHmT2rOmzPgJGRfUzMJALvckMUIUGkUCBUsN4PIcYVxWaCZQ4oK3OvpWTImJnhK EAhjLUXvVk4noflijcu+WIeng2q44A6VojYYyzdQstyQDHKLX6Ok5sVELkUzYcxiRzI1LFCZOWZC ZMmmOOP6wibbWuhcSgGo5gyKnkNpUhCbNK5oVGvAqVKGRCUSbvLqdDgnLRiixEfcXBocihAmZsMV 5liZJCikSImqsUnrJiR72o/DNpOw2xjkkjkVG5GQ5ciWJlxhyRcqajHrBc13JHmGRwDegyrvXE0Z xLzNmhGGSLZ0Jy2SGhGogwTKsmLguXizPYuN90GpqcMs1pDpGwQH3kMXbgqrsXMzA54hnKM5Md7G UtIW+UsviJaDBt7WgDhlrcszRSL5Z6YPIJF71KUkYDgkHIysTJjOEd045K82hnWh4CRUrYE8j18c NgpVCoJKgQUTDBzgHtFIzOZpMDSQHIFHJEjzOOpUiZEix4QuqRmk/bGORxmzksauzRhWMGpR5ldo NGj8marSvKDNU9R7AdWSrkUwSc5Dls0jZszJUKy1xOxkQHRxLByAaSpVRHLGHZPmOr4q83vaMi0q OqWNp2FV4hGeiWZcaL+sWw4GxHQbJr5uJ2MyBhMHHXkUNwFY5mhmbmY2DQoOd1Y8JypsYNxjIwOV JFCBIkWEF16xe4Ma4p025p23g7NrnGDvSURsSmz2jbrLixMTqDT8tzIkKpkJwhzIK5y1vUKHnrUI hWVhxeg2iW6s1Dt2ijkWBiBXSzkuZGCgwTN3HRGNwm5g4aB1zduYIjrcgQ6wpy4dwsLnHFCZgsUq hKZ4OC5YoOGC5wchjBuZECBguaH2UQs0Jher2C7iSikUOeWUc+W3R5y3YbWU70a0ZPCUYyJEbPRB B6qIO4oEwC/BSa3gSDuMIAiyEJqKZkhcJGhVstIArCiuRfq+DUj27QKFKZ3kjA2xhaj6FkcWaUhm O+XY3Ntt+bZ2W2jyexmyMDoo1zHwZ2GmO7F47x7kJzW1ZkZGVtsdVRSbyLDSViopObC82pMby8u2 bCRUTLi5sFjQYYoUHgaDh6zmvwV9IvM+wXc6G+2rXOW105iEdGlRvrGonelF4TFXbzF3jgvsCzLM XQrClaR3iU8QoJKFbRExCAhDEFyIk5Tu3d41VXTDDJmUYZDRxzNCJSitOhMlcoWPR4Nbxl373HPl GV6UdbblDJamhQJ15pFmPSPuOLEeTPIxmRI0pUkXjCcrLzQXxLAc5iiYHIJFxQzNJEsIFhtDQXDF AqFM723saj5Ycen5vpb5/z+lvXxhtinuHzFAIQ5B6IxU6UWx03RU0IEpcfzG9/V7HuysR3DAUjII Dj95BmBfFLXiez30+YOkYPlWIJ8hitPnP1PmJRH6Rt/KdYTYeATeY9giBRJgEaiCIKPZIwKcGyVV Wgysk6FgMiIMYoshQhJheMyEsaD2h+KkIB0D0DQKjcNRrGSQyHBoNh9ql401vqvDO/di+5QH+0P0 /5ec9Zm/O3h7KcDaO1DMjIRgxWQISECT+uHeOtpJhy7DvmZhl3eiGruJnzzsJJDdqRRVosQc4Q5s VZ9cfhhk5jILLff/xyWr/Qd2iJDYYNX10AZQyRzbkWpU9wuaLebNMxMs1/cK1TsW0MXKQA4od9yj l5RWX2qZjBCWgz3lVVnVqmFOqQsyjGmXLjMTclXxAtz2si/rj4JNBVWXlFQe3R3lZqzhrfVuVwf6 RBkwJloOSqLRf1eXmCs3RzrXjXBKCRULNIe7vP/vKs33gzALlZxwnF5LZk1GOonOVyFizPo1oNa5 6hzO0iT+blcHUZWdcxiAr1XHUrE9WSAriZPyYzn0zPH5zOGZhZOmfhRwpnUad4omjTmKkE6r/qyr Vu1WZJ2LgPaB1yIQSeAe8/WcPRsGbnDCdeX3msCVVnu+lm7nAx9H2+8cvsfbaiWFqJZbbdOQMIoM ChCwLADPWQrIMIMDGBZe35+UnwIMYSEshFD9TFeWyFoDn4T8s9zfH9x5fj8zynIgWtOe6SPIYSPq P0HsPqMDGBjXIccpMoWGLzvPqMSBAxNSF+wWBgQc4n11CSrImJYcNyM2eUbxNBYhvv+VOzMSlh9c RpQTFxKQNgxkTrGC0ivXuXXxevfEILMP89EgBOTTu/e/0Yn8ES2pQvZ7C8XA0YNqFchwPZMiEdYP FHf4klD5uaSAsBgJfayiCO81UgyYFxFRaIDYHK79NF5JZmjSJKvvD8nHyPHo1heeB08zkZl56Flh IidQSOo0ET3DkihmUMzsUqeYZFSRqZjkRypUsRImZUYiScqOm+RWRLDSd3dWTNJrLwctNZoF4ai8 neOSKFBzURLR81I07EtZFJO5qF4c5dAXDIMvHS0D0ITYHGZ4k/YqAdWiwAUQgwLnmdT1FjyHzGOx MYkUPQOMOdj1EyIULjm84l51jl9BqzgUIlxMYtNBAkMSKj1MtZgbP4rPMYTWgIzcQN5mJi4woSMI Yy2IxelvamB2mwsGHlvNGE+3xYZqG88+fWRNoWIMD0wG0iaF4fnOEfHE5fC4TqKBM23ahkkf4U6D gQR3QgWpDqHv4Ab94bEeRxOlA2ccvOm3Tmqi9BLrh18gRgOMOM7iYYfe+yBIoRc6DWaig2EhfWYY nymR8h0+aweyJgLmiQCcuZlDwZETcBWHNDgY2QluOpExSNDbbVJCklQvHAeBampucGhmXNDlzQdB iRMdGygd/Cz3Y4+oHk+68TQ5zzmw6Ch/HFPsVKvbA/TRwNH8gZxvL5z2Ma9RLW270KY4AYNwY2kZ ok0/l8C851NJATaHvUJiJhCkvfgvQjMkNQ+D1d6opNyMBvXkWA+8shvmOjshqGAoIUx0WW8UBpDc 9Z9AtOL/J85v7j3ljSbToeo4ol5Xp53tlrlLpiQh1RjS3VPU2BxJDl+JYeRpITPIuHzGNxAgRIGw tGHXyIMBMlikiptB3gd4nIxjB3QOoLBvpaiBeK8OlEVr3DEPiDNsMjYaDDkZkSsIDjEtyD0C0w2S Otk9eO18suWyWJ5+XWYUusKEDTOV5ca4JAK/5jWSigocjgx8YH1CzVgCoKhbtx04DdD/oGXdXamI dfJQSvRQSY6t6nuTBQHIdGY8sRfS+UQ96WR9cSSBGAvBB8buWWlBU9u4tG/GrcGlOMEE0HJYBwRd A+w7zn562V4gXHkB27bwi1GGUmIoPFTvIcHJADd4TEUMw6ReKJ7KIfa/VWBMlKIsFDccxzjg5eT4 zrOBIXsbyk9Y5ae4tPVfYLS4sMhyowKzQYECZIwHcoTIFSRc+jqSWxqUPuWPh8ORmam5/zsccH1+ nBmkivLuki1AxeAkP9gA07IR3IB0A6W4Tud9RSkkSZCc7wT6EDCOyaFmK4TnkhU8IdoxAkGbqtFr Zg0HXBBtxvoai3Ia+4OjM5M4hEto99FYtqFOfGCFQgjvwHIv9ipSiLd3HSbZQMmTJkJQCpGKVoNV spYT0kTmK0mLCQSORtOo97eYyfK67SUPGtjZ9kz7KdcyITCpg486XEEJE5QaPgPFCQNzU2bR4iYO 37Io4npSAP8iPA5NO71iuJNvQHjYJP0sNHxL+0dnue49AdxCII9IozQ9HuNSaB0DpBj69Pyk+iVD +sLJYgVVOPdd6kanGIJn10Hw7h0usyRo+3iM2KB2ShEF7jiF2hoj9btAvXcJKcPEBjbMcuP4eqqD d+KyQIDILCijlRclwv+I6hwHoHSQFYFOzjifaUPEkBpn8wG8ZgbCgaR3oAbxWxwiCcOVOmpoJePx seRCpxj4ZACr17V1WAuoXEF7DkoXYrQVKFAXWg0o0Hm9UCDQ7CByCzMpDiYGpvPKdxU1XctgHM5C nA+sV6EMwB5T7MlWvEvejM8ndGmmkgXgNxQTvPvR0bjVzaHdESBFQyQ7oC2T9iF4QbxeZWhx0lqy Fh6IXalbBo/nMEpNGSk4DU2iMu9lPkEYO4UgsaRFI7KpNb6XZfA3ITBYkGkAz0au8V6VPMHGj1Yz r38HlYxk5KhvKNIOUIFL1dWYOc1FFT7rZx+sbwXUbdhjcF2I2/FCJC1INiC9TXAWlQN6AcVyPgkj 7Qn77TOExTDANBpRQdmHqfz1fhKIlHuKlV96OQbyxZUiEFcvxdAD5Sq5lMQMCwWSjYVi9EHGr+cQ 1lR1VyMinrcVAcgMEFLAtIaR5fBGv63vK/CgevT3tSlDw+UmITSnKNgwA0slID3ZSCyELIFk1qA8 fXpi/5Q9nUoD6O82z5RW+ty0eZatTcPLz3gPgOrFDCPJRDcOUFXHsG35gpAhIEIIxPi3la+JgGcq OWgCAOBWn8TTI3Cv46XrtCyPMHNZXNeZ34TAVxGD+iovi6SBhQUulxtnuFLbTDUfhbkvwlBy97Lm L+Q2u6GDekaEANXAS9xe0eYHHFTizRdprPeT3+9CgB8B+A+KLU/KhQc6p+0yKne+ZZNID3h3KGKX D1DiVcPtXDo4Z+1h7g+lY/mchcUHJId47mUWUEwsF+IMh2kz2ir+4tjg08R3zmcLznQRmzmSxqgQ pE2gVA62G4oNRqOq4V0jtDwplbQiUOo0FkhD+hlXJsXuMopuxbzurrql3VJALuQWkuJ4UAQUJrvC oQoHEXEaIHQMRKobA1PAmbWh1j/Bfqw1Bz0VzB0BxgZyfgOdCjo2gPL25YsIBoAlJCA4FCgNEIi+ 4aNVgkWQeG3HpsmA1sQdIkT7HiAe9vpHttAzHllbAy/RgumVDCkiubS0dNKjWcjvD2l12ag3gxCg olIhiidWwQBTYCIvEtsCJkGRvIkw/PJAnTMdWPnO6Aukb1S4UufqJ2VBpcOaKLUA1PcOkE2cwruR czgQ1no/F1H/g7ApH0FEYJSCWUUpYJQrKUjKJQaJYjAhhtzLs1GeiLAfADfyErRgyDIucV/en0nA 8tOUQ8eU2m0TTA24xFVVVVVUktCV8ufZ9lXeDr08xxGEkbeaxq8lGxfwtVtG7AvIoUCwWSUUBxD8 EOQM/yHrzJj5xqNRzgwcrlzoP7gCMAK3Dw13jCoejY5vPmHt7B0c3RH6zhWc1gA3DevJoJGwBtga q4bQcxcDoNrzF/cQ3l4mj1uR5gfofACgGwV8SLAy3DID0L2sdBMNx3lsilLlKXXFriWLWK2JatJx DnfUoDAMopc0Fz73XKkqN1QbRFsO49g3CBxCuOA9KweYepfvOpyepH0jtADgQ6Tu159A9QpoD4j6 QoCjC/0AqZZiy4MIwpvX0PwwyHiOf2aBCxuJLtgXu/OkS0AVzqtAtFAgdP6XzIAL0Lu4B6zpFkrO ArybCpPFDyPK0RqmYhdEmFCj7xX8uUHn2+4zmh9obkooIbwdxbTuqiwy+TeL4TSQSUrO/PCi6dwz ttKNhIEWy6FuQ8ylrDB1nO6QaefrVoK8q8plgDqUBxvTgT+/age7EOMfT54Jp+4fUcB5g4Nx5xih J/7OuowPiIII/1L/xdyRThQkJ4yUwwA=