diff --git a/doc/ChangeLog b/doc/ChangeLog index a7965c200..49fbe587a 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,5 +1,8 @@ 2008-07-05 Vadim Kurland + * PolicyCompiler_pf_writers.cpp (PrintRule::_printDstService): + Support for tos matching in compiler for pf. + * PolicyCompiler_PrintRule.cpp (PrintRule::_printIP): Support for TOS and DSCP matching in compiler for iptables. diff --git a/src/pflib/PolicyCompiler_pf.cpp b/src/pflib/PolicyCompiler_pf.cpp index 471ba3680..5cc6d5cf8 100644 --- a/src/pflib/PolicyCompiler_pf.cpp +++ b/src/pflib/PolicyCompiler_pf.cpp @@ -34,6 +34,7 @@ #include "fwbuilder/ICMPService.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" +#include "fwbuilder/TagService.h" #include "fwbuilder/Policy.h" #include "fwbuilder/Interface.h" #include "fwbuilder/Firewall.h" @@ -875,53 +876,6 @@ bool PolicyCompiler_pf::splitIfInterfaceInRE::processNext() return true; } -bool PolicyCompiler_pf::separateSrcPort::processNext() -{ - PolicyRule *rule=getNext(); if (rule==NULL) return false; - - RuleElementSrv *rel= rule->getSrv(); - - if (rel->size()==1) { - tmp_queue.push_back(rule); - return true; - } - - list services; - for (FWObject::iterator i=rel->begin(); i!=rel->end(); i++) { - - FWObject *o= *i; - if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); - Service *s=Service::cast(o); - assert(s!=NULL); - - if ( TCPService::isA(s) || UDPService::isA(s) ) { - int srs=TCPUDPService::cast(s)->getSrcRangeStart(); - int sre=TCPUDPService::cast(s)->getSrcRangeEnd(); - - compiler->normalizePortRange(srs,sre); - - if (srs!=0 || sre!=0) { - PolicyRule *r= PolicyRule::cast( - compiler->dbcopy->create(PolicyRule::TYPENAME) ); - compiler->temp_ruleset->add(r); - r->duplicate(rule); - RuleElementSrv *nsrv=r->getSrv(); - nsrv->clearChildren(); - nsrv->addRef( s ); - tmp_queue.push_back(r); - services.push_back(s); - } - } - } - for (list::iterator i=services.begin(); i!=services.end(); i++) - rel->removeRef( (*i) ); - - if (!rel->isAny()) - tmp_queue.push_back(rule); - - return true; -} - bool PolicyCompiler_pf::createTables::processNext() { PolicyCompiler_pf *pf_comp=dynamic_cast(compiler); @@ -958,6 +912,83 @@ bool PolicyCompiler_pf::printScrubRule::processNext() return true; } + + + + + +PolicyCompiler_pf::separateServiceObject::separateServiceObject( + const string &name) : PolicyRuleProcessor(name) +{ +} + +bool PolicyCompiler_pf::separateServiceObject::processNext() +{ + PolicyRule *rule=getNext(); if (rule==NULL) return false; + + RuleElementSrv *rel= rule->getSrv(); + + if (rel->size()==1) { + tmp_queue.push_back(rule); + return true; + } + + list services; + for (FWObject::iterator i=rel->begin(); i!=rel->end(); i++) + { + FWObject *o= *i; + if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); + Service *s=Service::cast(o); + assert(s!=NULL); + + if (condition(s)) + { + PolicyRule *r= PolicyRule::cast( + compiler->dbcopy->create(PolicyRule::TYPENAME) ); + compiler->temp_ruleset->add(r); + r->duplicate(rule); + RuleElementSrv *nsrv=r->getSrv(); + nsrv->clearChildren(); + nsrv->addRef( s ); + tmp_queue.push_back(r); + services.push_back(s); + } + } + for (list::iterator i=services.begin(); i!=services.end(); i++) + rel->removeRef( (*i) ); + + if (!rel->isAny()) + tmp_queue.push_back(rule); + + return true; +} + + +bool PolicyCompiler_pf::separateSrcPort::condition(const Service *srv) +{ + if ( TCPService::isA(srv) || UDPService::isA(srv) ) + { + int srs = TCPUDPService::constcast(srv)->getSrcRangeStart(); + int sre = TCPUDPService::constcast(srv)->getSrcRangeEnd(); + + compiler->normalizePortRange(srs,sre); + + return (srs!=0 || sre!=0); + } + return false; +} + +bool PolicyCompiler_pf::separateTagged::condition(const Service *srv) +{ + return ( TagService::isA(srv)); +} + +bool PolicyCompiler_pf::separateTOS::condition(const Service *srv) +{ + const IPService *ip = IPService::constcast(srv); + return (ip && !ip->getTOSCode().empty()); +} + void PolicyCompiler_pf::compile() { cout << " Compiling " << fw->getName(); @@ -1066,10 +1097,10 @@ void PolicyCompiler_pf::compile() add( new InterfacePolicyRules( "process interface policy rules and store interface ids") ); - add( new splitIfFirewallInSrc( "split rule if firewall is in Src" )); - add( new splitIfFirewallInDst( "split rule if firewall is in Dst" )); - add( new fillDirection( "determine directions" )); - add( new SplitDirection( "split rules with direction 'both'" )); + add( new splitIfFirewallInSrc("split rule if firewall is in Src" )); + add( new splitIfFirewallInDst("split rule if firewall is in Dst" )); + add( new fillDirection("determine directions" )); + add( new SplitDirection("split rules with direction 'both'" )); add( new addLoopbackForRedirect( "add loopback to rules that permit redirected services" ) ); add( new ExpandMultipleAddresses( @@ -1077,12 +1108,15 @@ void PolicyCompiler_pf::compile() add( new dropRuleWithEmptyRE("drop rules with empty rule elements")); add( new checkForDynamicInterfacesOfOtherObjects( "check for dynamic interfaces of other hosts and firewalls" )); - add( new MACFiltering( "verify for MAC address filtering" )); - add( new checkForUnnumbered( "check for unnumbered interfaces" )); - add( new addressRanges( "expand address range objects" )); - add( new splitServices( "split rules with different protocols")); + add( new MACFiltering("verify for MAC address filtering" )); + add( new checkForUnnumbered("check for unnumbered interfaces" )); + add( new addressRanges("expand address range objects" )); + add( new splitServices("split rules with different protocols")); add( new separateTCPWithFlags("separate TCP services with flags" )); add( new separateSrcPort("split on TCP and UDP with source ports")); + add( new separateTagged("split on TagService")); + add( new separateTOS("split on IPService with TOS")); + add( new verifyCustomServices( "verify custom services for this platform")); // add( new ProcessScrubOption( "process 'scrub' option" )); diff --git a/src/pflib/PolicyCompiler_pf.h b/src/pflib/PolicyCompiler_pf.h index 268eacc05..6aa99e23a 100644 --- a/src/pflib/PolicyCompiler_pf.h +++ b/src/pflib/PolicyCompiler_pf.h @@ -354,12 +354,55 @@ namespace fwcompiler { eliminateDuplicatesInRE(n,libfwbuilder::RuleElementSrv::TYPENAME) {} }; + /** + * separate service object that satisfies condition + * implemented in the virtual method "condition" so we have + * exactly one such object per rule. + */ + class separateServiceObject : public PolicyRuleProcessor + { + protected: + virtual bool condition(const libfwbuilder::Service *srv) =0; + public: + separateServiceObject(const std::string &name); + virtual bool processNext(); + }; + /** * separate TCP/UDP services that specify source port (can * not be used in combination with destination port with * multiport) */ - DECLARE_POLICY_RULE_PROCESSOR(separateSrcPort); + class separateSrcPort : public separateServiceObject + { + protected: + virtual bool condition(const libfwbuilder::Service *srv); + public: + separateSrcPort(const std::string &name) : separateServiceObject(name) {} + }; + + /** + * separate Tag services so we have exactly one per rule. + */ + class separateTagged : public separateServiceObject + { + protected: + virtual bool condition(const libfwbuilder::Service *srv); + public: + separateTagged(const std::string &name) : separateServiceObject(name) {} + }; + + /** + * separate IPService objects with tos attrubute so we have + * exactly one per rule. + */ + class separateTOS : public separateServiceObject + { + protected: + virtual bool condition(const libfwbuilder::Service *srv); + public: + separateTOS(const std::string &name) : separateServiceObject(name) {} + }; class printScrubRule : public PolicyRuleProcessor diff --git a/src/pflib/PolicyCompiler_pf_writers.cpp b/src/pflib/PolicyCompiler_pf_writers.cpp index 72337ebe4..c8620dbbc 100644 --- a/src/pflib/PolicyCompiler_pf_writers.cpp +++ b/src/pflib/PolicyCompiler_pf_writers.cpp @@ -30,6 +30,7 @@ #include "fwbuilder/RuleElement.h" #include "fwbuilder/IPService.h" #include "fwbuilder/ICMPService.h" +#include "fwbuilder/ICMP6Service.h" #include "fwbuilder/TCPService.h" #include "fwbuilder/UDPService.h" #include "fwbuilder/CustomService.h" @@ -543,7 +544,10 @@ void PolicyCompiler_pf::PrintRule::_printDstService(RuleElementSrv *rel) if (ICMPService::isA(srv)) compiler->output << "icmp-type " << str << " "; else - compiler->output << str << " "; + if (ICMP6Service::isA(srv)) + compiler->output << "icmp6-type " << str << " "; + else + compiler->output << str << " "; } } if (TCPService::isA(srv)) @@ -551,9 +555,17 @@ void PolicyCompiler_pf::PrintRule::_printDstService(RuleElementSrv *rel) str=_printTCPFlags(TCPService::cast(srv)); if (!str.empty()) compiler->output << "flags " << str << " "; } - if (IPService::isA(srv) && - (srv->getBool("fragm") || srv->getBool("short_fragm")) ) + if (IPService::isA(srv)) + { + if (srv->getBool("fragm") || srv->getBool("short_fragm")) compiler->output << " fragment "; + const IPService *ip = IPService::constcast(srv); + string tos = ip->getTOSCode(); + string dscp = ip->getDSCPCode(); + if (!tos.empty()) compiler->output << " tos " << tos; + if (!dscp.empty()) + compiler->abort("PF does not support DSCP matching"); + } } else { string str; @@ -577,7 +589,10 @@ void PolicyCompiler_pf::PrintRule::_printDstService(RuleElementSrv *rel) compiler->output << "icmp-type { " << str << " } "; else { - compiler->output << str << " " << endl; + if (ICMP6Service::isA(srv)) + compiler->output << "icmp6-type { " << str << " } "; + else + compiler->output << str << " " << endl; } } } diff --git a/test/pf/objects-for-regression-tests.fwb b/test/pf/objects-for-regression-tests.fwb index 4b3152a5f..6c99e9831 100644 --- a/test/pf/objects-for-regression-tests.fwb +++ b/test/pf/objects-for-regression-tests.fwb @@ -1,20 +1,123 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + - - - - - - + + + + + + @@ -43,28 +146,28 @@ - + - + - + - + - + - + @@ -72,16 +175,16 @@ - - + + - - + + @@ -96,8 +199,8 @@ - - + + @@ -112,16 +215,16 @@ - - + + - - + + @@ -133,40 +236,40 @@ - - + + - - - + + + - - + + - - + + - - + + @@ -178,8 +281,8 @@ - - + + @@ -191,10 +294,10 @@ - - + + - + @@ -205,10 +308,10 @@ - - - - + + + + @@ -222,10 +325,10 @@ - - + + - + @@ -239,8 +342,8 @@ - - + + @@ -256,8 +359,8 @@ - - + + @@ -273,8 +376,8 @@ - - + + @@ -290,8 +393,8 @@ - - + + @@ -307,8 +410,8 @@ - - + + @@ -324,8 +427,8 @@ - - + + @@ -341,9 +444,9 @@ - - - + + + @@ -359,7 +462,7 @@ - + @@ -372,7 +475,7 @@ - + @@ -385,7 +488,7 @@ - + @@ -397,35 +500,36 @@ - - - - - - - - - - + + + + + + + + + + - - + + - - - - - - - + + + + + + + - - + + + @@ -483,29 +587,32 @@ - - + + - - + + + + + - - - - - - + + + + + + - + -m ip_conntrack_talk -m ip_nat_talk - + @@ -515,15 +622,15 @@ - - - + + + - + - + @@ -544,7 +651,7 @@ - + @@ -565,7 +672,7 @@ - + @@ -586,7 +693,7 @@ - + @@ -609,7 +716,7 @@ - + @@ -626,7 +733,7 @@ - + @@ -646,7 +753,7 @@ - + @@ -667,7 +774,7 @@ - + @@ -682,7 +789,7 @@ - + @@ -699,7 +806,7 @@ - + @@ -724,7 +831,7 @@ - + @@ -746,7 +853,7 @@ - + @@ -769,7 +876,7 @@ - + @@ -792,7 +899,7 @@ - + @@ -820,7 +927,7 @@ - + @@ -849,7 +956,7 @@ - + @@ -886,7 +993,7 @@ - + @@ -915,7 +1022,7 @@ - + @@ -939,7 +1046,7 @@ - + @@ -963,7 +1070,7 @@ - + @@ -986,7 +1093,7 @@ - + @@ -1009,7 +1116,7 @@ - + @@ -1029,7 +1136,7 @@ - + @@ -1053,7 +1160,7 @@ - + @@ -1080,14 +1187,14 @@ - + - + - - + + @@ -1215,9 +1322,9 @@ - + - + @@ -1238,7 +1345,7 @@ - + @@ -1259,7 +1366,7 @@ - + @@ -1280,7 +1387,7 @@ - + @@ -1301,7 +1408,7 @@ - + @@ -1323,7 +1430,7 @@ - + @@ -1345,7 +1452,7 @@ - + @@ -1366,7 +1473,7 @@ - + @@ -1387,7 +1494,7 @@ - + @@ -1408,7 +1515,7 @@ - + @@ -1429,7 +1536,7 @@ - + @@ -1450,7 +1557,7 @@ - + @@ -1471,7 +1578,7 @@ - + @@ -1492,7 +1599,7 @@ - + @@ -1513,7 +1620,7 @@ - + @@ -1537,7 +1644,7 @@ - + @@ -1554,7 +1661,7 @@ - + @@ -1574,7 +1681,7 @@ - + @@ -1592,7 +1699,7 @@ - + @@ -1609,7 +1716,7 @@ - + @@ -1627,7 +1734,7 @@ - + @@ -1647,7 +1754,7 @@ - + @@ -1667,7 +1774,7 @@ - + @@ -1685,7 +1792,7 @@ - + @@ -1709,7 +1816,7 @@ - + @@ -1734,7 +1841,7 @@ - + @@ -1755,7 +1862,7 @@ - + @@ -1776,7 +1883,7 @@ - + @@ -1798,7 +1905,7 @@ - + @@ -1822,7 +1929,7 @@ - + @@ -1844,7 +1951,7 @@ - + @@ -1864,7 +1971,7 @@ - + @@ -1884,7 +1991,7 @@ - + @@ -1902,7 +2009,7 @@ - + @@ -1924,19 +2031,19 @@ - + - + - + - + - + @@ -2062,9 +2169,9 @@ - + - + @@ -2085,7 +2192,7 @@ - + @@ -2107,7 +2214,7 @@ - + @@ -2130,7 +2237,7 @@ - + @@ -2149,7 +2256,7 @@ - + @@ -2167,7 +2274,7 @@ - + @@ -2189,10 +2296,10 @@ - - + + - + @@ -2267,9 +2374,9 @@ - + - + @@ -2293,7 +2400,7 @@ - + @@ -2318,7 +2425,7 @@ - + @@ -2342,7 +2449,7 @@ - + @@ -2366,7 +2473,7 @@ - + @@ -2391,7 +2498,7 @@ - + @@ -2415,7 +2522,7 @@ - + @@ -2439,7 +2546,7 @@ - + @@ -2464,7 +2571,7 @@ - + @@ -2488,7 +2595,7 @@ - + @@ -2509,7 +2616,7 @@ - + @@ -2531,7 +2638,7 @@ - + @@ -2552,7 +2659,7 @@ - + @@ -2575,7 +2682,7 @@ - + @@ -2596,7 +2703,7 @@ - + @@ -2617,7 +2724,7 @@ - + @@ -2638,7 +2745,7 @@ - + @@ -2659,7 +2766,7 @@ - + @@ -2680,7 +2787,7 @@ - + @@ -2701,7 +2808,7 @@ - + @@ -2722,7 +2829,7 @@ - + @@ -2743,7 +2850,7 @@ - + @@ -2764,7 +2871,7 @@ - + @@ -2785,7 +2892,7 @@ - + @@ -2806,7 +2913,7 @@ - + @@ -2827,7 +2934,7 @@ - + @@ -2848,7 +2955,7 @@ - + @@ -2869,7 +2976,7 @@ - + @@ -2890,7 +2997,7 @@ - + @@ -2916,7 +3023,7 @@ - + @@ -2936,7 +3043,7 @@ - + @@ -2958,7 +3065,7 @@ - + @@ -2983,7 +3090,7 @@ - + @@ -3009,7 +3116,7 @@ - + @@ -3035,7 +3142,7 @@ - + @@ -3057,7 +3164,7 @@ - + @@ -3078,7 +3185,7 @@ - + @@ -3102,7 +3209,7 @@ - + @@ -3121,7 +3228,7 @@ - + @@ -3140,7 +3247,7 @@ - + @@ -3160,7 +3267,7 @@ - + @@ -3178,7 +3285,7 @@ - + @@ -3199,7 +3306,7 @@ - + @@ -3222,20 +3329,20 @@ - + - + - + - + - - + + @@ -3369,9 +3476,9 @@ - + - + @@ -3394,7 +3501,7 @@ - + @@ -3417,7 +3524,7 @@ - + @@ -3438,7 +3545,7 @@ - + @@ -3461,7 +3568,7 @@ - + @@ -3478,7 +3585,7 @@ - + @@ -3496,7 +3603,7 @@ - + @@ -3514,7 +3621,7 @@ - + @@ -3534,7 +3641,7 @@ - + @@ -3556,7 +3663,7 @@ - + @@ -3578,7 +3685,7 @@ - + @@ -3601,7 +3708,7 @@ - + @@ -3621,7 +3728,7 @@ - + @@ -3644,19 +3751,19 @@ - + - + - + - + - + @@ -3777,9 +3884,9 @@ - + - + @@ -3802,7 +3909,7 @@ - + @@ -3827,7 +3934,7 @@ - + @@ -3852,7 +3959,7 @@ - + @@ -3874,14 +3981,14 @@ - - + + - + - - + + @@ -3958,10 +4065,10 @@ - + - + @@ -3978,7 +4085,7 @@ - + @@ -4000,19 +4107,19 @@ - + - + - + - + - + @@ -4085,10 +4192,10 @@ - + - + @@ -4108,7 +4215,7 @@ - + @@ -4128,19 +4235,19 @@ - + - + - + - + - + @@ -4213,9 +4320,9 @@ - + - + @@ -4236,7 +4343,7 @@ - + @@ -4257,7 +4364,7 @@ - + @@ -4278,7 +4385,7 @@ - + @@ -4299,7 +4406,7 @@ - + @@ -4320,7 +4427,7 @@ - + @@ -4341,7 +4448,7 @@ - + @@ -4362,7 +4469,7 @@ - + @@ -4383,7 +4490,7 @@ - + @@ -4406,7 +4513,7 @@ - + @@ -4426,7 +4533,7 @@ - + @@ -4446,7 +4553,7 @@ - + @@ -4464,7 +4571,7 @@ - + @@ -4482,7 +4589,7 @@ - + @@ -4500,7 +4607,7 @@ - + @@ -4522,17 +4629,17 @@ - - - + + + - - + + - - + + - + @@ -4575,9 +4682,9 @@ - + - + @@ -4598,7 +4705,7 @@ - + @@ -4621,7 +4728,7 @@ - + @@ -4641,7 +4748,7 @@ - + @@ -4659,7 +4766,7 @@ - + @@ -4677,7 +4784,7 @@ - + @@ -4695,7 +4802,7 @@ - + @@ -4717,11 +4824,11 @@ - + - - + + @@ -4797,9 +4904,9 @@ - + - + @@ -4820,7 +4927,7 @@ - + @@ -4841,7 +4948,7 @@ - + @@ -4863,7 +4970,7 @@ - + @@ -4887,7 +4994,7 @@ - + @@ -4905,7 +5012,7 @@ - + @@ -4923,7 +5030,7 @@ - + @@ -4941,7 +5048,7 @@ - + @@ -4959,7 +5066,7 @@ - + @@ -4979,7 +5086,7 @@ - + @@ -4999,7 +5106,7 @@ - + @@ -5017,7 +5124,7 @@ - + @@ -5035,7 +5142,7 @@ - + @@ -5054,7 +5161,7 @@ - + @@ -5073,7 +5180,7 @@ - + @@ -5092,7 +5199,7 @@ - + @@ -5114,12 +5221,12 @@ - - + + - - + + @@ -5211,9 +5318,9 @@ - + - + @@ -5234,7 +5341,7 @@ - + @@ -5255,7 +5362,7 @@ - + @@ -5276,7 +5383,7 @@ - + @@ -5297,7 +5404,7 @@ - + @@ -5318,7 +5425,7 @@ - + @@ -5339,7 +5446,7 @@ - + @@ -5362,7 +5469,7 @@ - + @@ -5380,7 +5487,7 @@ - + @@ -5400,7 +5507,7 @@ - + @@ -5420,7 +5527,7 @@ - + @@ -5440,7 +5547,7 @@ - + @@ -5460,7 +5567,7 @@ - + @@ -5481,7 +5588,7 @@ - + @@ -5501,7 +5608,7 @@ - + @@ -5522,7 +5629,7 @@ - + @@ -5541,7 +5648,7 @@ - + @@ -5576,7 +5683,7 @@ - + @@ -5594,7 +5701,7 @@ - + @@ -5616,12 +5723,12 @@ - - + + - - + + @@ -5713,9 +5820,9 @@ - + - + @@ -5736,7 +5843,7 @@ - + @@ -5759,7 +5866,7 @@ - + @@ -5785,7 +5892,7 @@ - + @@ -5803,7 +5910,7 @@ - + @@ -5821,7 +5928,7 @@ - + @@ -5839,7 +5946,7 @@ - + @@ -5857,7 +5964,7 @@ - + @@ -5875,7 +5982,26 @@ - + + + + + + + + + + + + + + + + + + + + @@ -5893,7 +6019,7 @@ - + @@ -5912,7 +6038,7 @@ - + @@ -5931,7 +6057,7 @@ - + @@ -5958,7 +6084,7 @@ - + @@ -5980,15 +6106,15 @@ - + - - + + - - + + @@ -6109,9 +6235,9 @@ - + - + @@ -6139,7 +6265,7 @@ - + @@ -6172,7 +6298,7 @@ - + @@ -6200,7 +6326,7 @@ - + @@ -6228,7 +6354,7 @@ - + @@ -6259,7 +6385,7 @@ - + @@ -6279,7 +6405,7 @@ - + @@ -6306,15 +6432,15 @@ - - - + + + - - + + - - + + @@ -6429,9 +6555,9 @@ - + - + @@ -6452,7 +6578,7 @@ - + @@ -6475,7 +6601,7 @@ - + @@ -6501,7 +6627,7 @@ - + @@ -6519,7 +6645,7 @@ - + @@ -6540,7 +6666,7 @@ - + @@ -6561,7 +6687,7 @@ - + @@ -6579,7 +6705,7 @@ - + @@ -6600,7 +6726,7 @@ - + @@ -6618,7 +6744,7 @@ - + @@ -6637,7 +6763,7 @@ - + @@ -6656,7 +6782,7 @@ - + @@ -6683,7 +6809,7 @@ - + @@ -6705,7 +6831,7 @@ - + @@ -6723,7 +6849,7 @@ - + @@ -6745,7 +6871,7 @@ - + @@ -6763,7 +6889,7 @@ - + @@ -6782,7 +6908,7 @@ - + @@ -6805,15 +6931,15 @@ - + - - + + - - + + @@ -6934,9 +7060,9 @@ - + - + @@ -6957,7 +7083,7 @@ - + @@ -6980,7 +7106,7 @@ - + @@ -7005,7 +7131,7 @@ - + @@ -7030,7 +7156,7 @@ - + @@ -7073,7 +7199,7 @@ - + @@ -7115,7 +7241,7 @@ - + @@ -7133,7 +7259,7 @@ - + @@ -7155,17 +7281,17 @@ - - + + - - + + - - + + - - + + @@ -7277,10 +7403,10 @@ - + - + @@ -7298,7 +7424,7 @@ - + @@ -7316,7 +7442,7 @@ - + @@ -7336,10 +7462,10 @@ - + - + @@ -7392,9 +7518,9 @@ - + - + @@ -7415,7 +7541,7 @@ - + @@ -7438,7 +7564,7 @@ - + @@ -7459,7 +7585,7 @@ - + @@ -7494,7 +7620,7 @@ - + @@ -7529,7 +7655,7 @@ - + @@ -7551,11 +7677,11 @@ - + - - + + @@ -7684,9 +7810,9 @@ - + - + @@ -7707,7 +7833,7 @@ - + @@ -7730,7 +7856,7 @@ - + @@ -7751,7 +7877,7 @@ - + @@ -7786,7 +7912,7 @@ - + @@ -7821,7 +7947,7 @@ - + @@ -7843,11 +7969,11 @@ - + - - + + @@ -7976,9 +8102,9 @@ - + - + @@ -7999,7 +8125,7 @@ - + @@ -8022,7 +8148,7 @@ - + @@ -8043,7 +8169,7 @@ - + @@ -8078,7 +8204,7 @@ - + @@ -8113,7 +8239,7 @@ - + @@ -8135,11 +8261,11 @@ - + - - + + @@ -8268,9 +8394,9 @@ - + - + @@ -8291,7 +8417,7 @@ - + @@ -8314,7 +8440,7 @@ - + @@ -8335,7 +8461,7 @@ - + @@ -8370,7 +8496,7 @@ - + @@ -8405,7 +8531,7 @@ - + @@ -8427,11 +8553,11 @@ - + - - + + @@ -8560,9 +8686,9 @@ - + - + @@ -8583,7 +8709,7 @@ - + @@ -8606,7 +8732,7 @@ - + @@ -8641,7 +8767,7 @@ - + @@ -8662,7 +8788,7 @@ - + @@ -8697,7 +8823,7 @@ - + @@ -8732,7 +8858,7 @@ - + @@ -8754,11 +8880,11 @@ - + - - + + @@ -8887,9 +9013,9 @@ - + - + @@ -8910,7 +9036,7 @@ - + @@ -8933,7 +9059,7 @@ - + @@ -8954,7 +9080,7 @@ - + @@ -8989,7 +9115,7 @@ - + @@ -9024,7 +9150,7 @@ - + @@ -9046,11 +9172,11 @@ - + - - + + @@ -9179,9 +9305,9 @@ - + - + @@ -9202,7 +9328,7 @@ - + @@ -9225,7 +9351,7 @@ - + @@ -9284,7 +9410,7 @@ - + @@ -9343,7 +9469,7 @@ - + @@ -9402,7 +9528,7 @@ - + @@ -9461,7 +9587,7 @@ - + @@ -9520,7 +9646,7 @@ - + @@ -9579,7 +9705,7 @@ - + @@ -9638,7 +9764,7 @@ - + @@ -9697,7 +9823,7 @@ - + @@ -9756,7 +9882,7 @@ - + @@ -9815,7 +9941,7 @@ - + @@ -9874,7 +10000,7 @@ - + @@ -9935,17 +10061,17 @@ - - + + - - + + - - + + - - + + @@ -10057,11 +10183,11 @@ - + - + @@ -10081,7 +10207,7 @@ - + @@ -10101,7 +10227,7 @@ - + @@ -10121,7 +10247,7 @@ - + @@ -10141,7 +10267,7 @@ - + @@ -10161,7 +10287,7 @@ - + @@ -10181,7 +10307,7 @@ - + @@ -10201,7 +10327,7 @@ - + @@ -10221,7 +10347,7 @@ - + @@ -10241,7 +10367,7 @@ - + @@ -10261,7 +10387,7 @@ - + @@ -10281,7 +10407,7 @@ - + @@ -10303,13 +10429,13 @@ - + - + - - - + + + @@ -10451,11 +10577,11 @@ - + - - + + @@ -10475,7 +10601,7 @@ - + @@ -10497,8 +10623,8 @@ - - + + @@ -10518,7 +10644,7 @@ - + @@ -10540,8 +10666,8 @@ - - + + @@ -10562,7 +10688,7 @@ - + @@ -10584,8 +10710,8 @@ - - + + @@ -10606,7 +10732,7 @@ - + @@ -10628,13 +10754,13 @@ - + - + - + @@ -10703,10 +10829,10 @@ - + - + @@ -10751,7 +10877,7 @@ - + @@ -10796,7 +10922,7 @@ - + @@ -10841,7 +10967,7 @@ - + @@ -10886,7 +11012,7 @@ - + @@ -10910,7 +11036,7 @@ - + @@ -10933,15 +11059,15 @@ - - + + - + - + - + @@ -11035,10 +11161,10 @@ - + - + @@ -11058,7 +11184,7 @@ - + @@ -11079,7 +11205,7 @@ - + @@ -11099,7 +11225,7 @@ - + @@ -11120,7 +11246,7 @@ - + @@ -11141,7 +11267,7 @@ - + @@ -11162,7 +11288,7 @@ - + @@ -11182,7 +11308,7 @@ - + @@ -11202,7 +11328,7 @@ - + @@ -11222,7 +11348,7 @@ - + @@ -11243,7 +11369,7 @@ - + @@ -11263,7 +11389,7 @@ - + @@ -11283,7 +11409,7 @@ - + @@ -11303,7 +11429,7 @@ - + @@ -11325,11 +11451,11 @@ - - + + - - + + @@ -11418,6 +11544,282 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -11441,120 +11843,26 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + + - - - + + + - + @@ -11565,9 +11873,9 @@ - + - + @@ -11588,7 +11896,7 @@ - + @@ -11613,7 +11921,7 @@ - + @@ -11655,7 +11963,7 @@ - + @@ -11676,7 +11984,7 @@ - + @@ -11697,7 +12005,7 @@ - + @@ -11715,7 +12023,7 @@ - + @@ -11737,7 +12045,7 @@ - + @@ -11757,7 +12065,7 @@ - + @@ -11776,7 +12084,7 @@ - + @@ -11798,7 +12106,7 @@ - + @@ -11818,7 +12126,7 @@ - + @@ -11845,14 +12153,14 @@ - - + + - + - - + + @@ -11974,9 +12282,9 @@ - + - + @@ -11999,7 +12307,7 @@ - + @@ -12020,7 +12328,7 @@ - + @@ -12041,7 +12349,7 @@ - + @@ -12059,7 +12367,7 @@ - + @@ -12079,7 +12387,7 @@ - + @@ -12097,7 +12405,7 @@ - + @@ -12115,7 +12423,7 @@ - + @@ -12137,14 +12445,14 @@ - - + + - + - - + + @@ -12272,10 +12580,10 @@ - + - + @@ -12295,7 +12603,7 @@ - + @@ -12315,7 +12623,7 @@ - + @@ -12333,7 +12641,7 @@ - + @@ -12355,7 +12663,7 @@ - + @@ -12373,7 +12681,7 @@ - + @@ -12395,7 +12703,7 @@ - + @@ -12415,7 +12723,7 @@ - + @@ -12442,10 +12750,10 @@ - - + + - + @@ -12568,10 +12876,10 @@ - + - + @@ -12591,7 +12899,7 @@ - + @@ -12611,7 +12919,7 @@ - + @@ -12629,7 +12937,7 @@ - + @@ -12651,7 +12959,7 @@ - + @@ -12669,7 +12977,7 @@ - + @@ -12691,7 +12999,7 @@ - + @@ -12711,7 +13019,7 @@ - + @@ -12738,10 +13046,10 @@ - - + + - + @@ -12873,7 +13181,7 @@ - + @@ -12896,63 +13204,63 @@ - + - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + - + @@ -12968,25 +13276,25 @@ - - - - - - + + + + + + - - - + + + - - - + + + - +