text:
y2="26.008" width="0.4" layer="1"/>
<via x="11.5" y="27" extent="1-16" drill="0.3"/>
<via x="13.5" y="24.75" extent="1-16" drill="0.3"/>
<wire x1="13.8" y1="23.17" x2="13.8" y2="24.45" width="0.2" layer="1"/>
<wire x1="13.8" y1="24.45" x2="13.5" y2="24.75" width="0.2" layer="1"/>
<wire x1="13.5" y1="24.75" x2="12.758" y2="24.75" width="0.2" layer="16"/>
<wire x1="12.758" y1="24.75" x2="11.5" y2="26.008" width="0.2" layer="16"/>
<wire x1="11.5" y1="26.008" x2="11.5" y2="27" width="0.2" layer="16"/>
</signal>
</signals>
<errors>
<approved hash="18,29,c98c7caf4eb5fb96"/>
<approved hash="18,29,1f22aa874a9dff38"/>
<approved hash="18,29,1d3694f374e9fd2c"/>
<approved hash="18,29,192ea89b4881f934"/>
<approved hash="18,29,230a952ff3354510"/>
<approved hash="18,29,ab6ed11751132b6a"/>
<approved hash="18,29,4e4bfa0becf458b4"/>
<approved hash="18,29,b569db105bec3595"/>
<approved hash="18,29,6f773b20bbdcef8b"/>
<approved hash="18,29,54b6f4f6e2f342b3"/>
<approved hash="18,29,658cc1db41d7e580"/>
<approved hash="18,29,1bec063c9c1026c6"/>
<approved hash="18,29,5ca27677321d80a2"/>
<approved hash="18,29,938b36aca09605b1"/>
<approved hash="18,29,e9dcbd49bd73e9e6"/>
<approved hash="18,29,ab6ed11751132b6a"/>
<approved hash="18,29,8ac7fa038cfcfc38"/>
<approved hash="18,29,8de5db105bef0d1a"/>
<approved hash="18,29,ef065920bbde0df8"/>
<approved hash="18,29,25d345baaebeced7"/>
<approved hash="18,29,124d3c644290c868"/>
<approved hash="18,29,16ab71179a1cfda0"/>
<approved hash="18,29,01f278fc52d2827b"/>
<approved hash="18,29,2fd41d4646e4d0a7"/>
<approved hash="18,29,07241b21912a8d2f"/>
<approved hash="18,29,014f6ed813f6d4c0"/>
<approved hash="18,29,dcb3711af1145cbd"/>
<approved hash="18,29,dcbcdea5b5a4b7bd"/>
<approved hash="18,29,dddf672f91212bd1"/>
<approved hash="18,29,ddd0cc1a271b36d1"/>
<approved hash="18,29,ec9180397d7bf4e9"/>
<approved hash="18,29,c854aa4241bf23a9"/>
<approved hash="18,29,0064b61b3ce78a98"/>
<approved hash="18,29,92b53d63bd9e1248"/>
<approved hash="18,29,0bbd1b2eed2ffdbc"/>
<approved hash="18,29,d6be0b618b6556ba"/>
<approved hash="18,29,f4351a72788d96ca"/>
<approved hash="18,29,1ac30fe3f9e2ecc2"/>
<approved hash="18,29,ee67392f4fd19899"/>
<approved hash="18,29,008aa863bd9e1577"/>
<approved hash="18,29,d6be0d6c6668bdba"/>
<approved hash="18,29,36106d72788d23ef"/>
<approved hash="18,29,25d1468dc68ba5d7"/>
<approved hash="18,29,ab6b1ee49ee52b6a"/>
<approved hash="18,29,318e5fdbdfddb188"/>
<approved hash="18,29,318936705d715a88"/>
<approved hash="18,29,30023a9658935207"/>
<approved hash="18,29,477e6bad7eae527d"/>
<approved hash="18,29,3bd44cfecc02bb28"/>
<approved hash="18,29,3979ecaa8eae5b7d"/>
<approved hash="18,29,e99e40b5c0b5699e"/>
<approved hash="18,29,155fda577ff91956"/>
<approved hash="18,29,a3e67a7788d9f9e9"/>
<approved hash="18,29,2f8b42b929454477"/>
<approved hash="18,29,effc1d47f64304f8"/>
<approved hash="18,29,b569db105bec3595"/>
<approved hash="18,29,6f773b20bbdcef8b"/>
<approved hash="18,29,e6cec1db41da66cf"/>
<approved hash="18,29,92b73d17bde81248"/>
<approved hash="18,29,92b795667e997948"/>
<approved hash="18,29,3bd451caba36d028"/>
<approved hash="18,29,4e039baa8eae5b07"/>
<approved hash="18,29,db8d91af84afce8d"/>
<approved hash="18,29,bb84de1b3ce2597d"/>
<approved hash="18,29,e646907822c1fb2f"/>
<approved hash="18,29,833ce9b87557b003"/>
<approved hash="18,29,4e4b31b25a4d25b4"/>
<approved hash="18,29,4e4aa085207bceb4"/>
<approved hash="18,29,2528a9dbbc2730d4"/>
<approved hash="18,29,d57bcde72f1a3786"/>
<approved hash="18,29,c4a1da09b8f4a65c"/>
<approved hash="18,29,30de86b41349a523"/>
<approved hash="18,29,54b6f4849f813fb3"/>
<approved hash="18,29,54b6f68f768ad4b3"/>
<approved hash="18,29,984a239ca39b184d"/>
<approved hash="18,29,984a2050cb57734d"/>
<approved hash="18,29,1d2b1619b01ebb2c"/>
<approved hash="18,29,06453c7ece79f442"/>
<approved hash="18,29,113cab652b609139"/>
<approved hash="18,29,9a1e596f2c69ef18"/>
<approved hash="18,29,6269ab652b63e26f"/>
<approved hash="18,29,1b7adcf657f59079"/>
<approved hash="18,29,0788ba9f5f9ae28d"/>
<approved hash="18,29,231716b5f0b2c510"/>
<approved hash="18,29,46e97c7ece79f4ee"/>
<approved hash="18,29,d0d06bfaebff50d5"/>
<approved hash="18,29,9a1e5a0cef0a2f18"/>
<approved hash="18,29,a3856bfaebfc2383"/>
<approved hash="18,29,1b7adc6a1769d079"/>
<approved hash="18,29,c6eb7a9f5f9ae3ee"/>
<approved hash="18,29,1d2b162ef629fd2c"/>
<approved hash="18,29,2317175631510510"/>
<approved hash="18,29,890dbc7ece79fb0a"/>
<approved hash="18,29,1bc72c72cc75fbc0"/>
<approved hash="18,29,1f3f285ac85dff38"/>
<approved hash="18,29,19332a46ca41f934"/>
<approved hash="18,29,f3d44da0afa511d1"/>
<approved hash="18,29,90742a9eaa9b1071"/>
<approved hash="18,29,1b858e88b8742d79"/>
<approved hash="18,29,3e1091b933459cec"/>
<approved hash="18,29,9a1e5aa0afa66f18"/>
<approved hash="18,29,e3212a9eaa986327"/>
<approved hash="18,29,1b7ae30ee80d1079"/>
<approved hash="18,29,1e70dfed5fee9e73"/>
<approved hash="18,29,86773a9f5f9ae372"/>
<approved hash="18,29,75d261c01ec70ad5"/>
<approved hash="18,29,70dc5a70da77f0db"/>
<approved hash="18,29,1b7a7ebbfeb89b79"/>
<approved hash="18,29,1b7b9800ae022d79"/>
<approved hash="18,29,1e7043adc3ae9e73"/>
<approved hash="18,29,8a15410d540e9f16"/>
<approved hash="18,29,3eee873125339cec"/>
<approved hash="18,29,029a506b5a6d089c"/>
<approved hash="18,29,349f4f9845943e93"/>
<approved hash="18,29,c8651c04b6396258"/>
<approved hash="18,29,b7db2c0c06089ddf"/>
<approved hash="18,29,042043759574d221"/>
<approved hash="18,29,10217f92a990c623"/>
<approved hash="18,29,2c237390a5aefa1d"/>
<approved hash="18,29,381d07aed1acee1f"/>
<approved hash="18,29,341f1baccdaae219"/>
<approved hash="18,29,c0192faaf9a8161b"/>
<approved hash="18,29,dc1b23a8f5a60a15"/>
<approved hash="18,29,e81537a6e1a43e17"/>
<approved hash="18,29,9abff0565a5230bb"/>
<approved hash="18,29,e417cba41da23211"/>
<approved hash="18,29,90a4ca4d60493aa0"/>
<approved hash="18,29,7980f1eb6c44f44c"/>
<approved hash="18,29,415d7c21c8c2c1bf"/>
<approved hash="18,29,6e9d3704373c6ea5"/>
<approved hash="18,29,e751b1e667de3169"/>
<approved hash="18,29,21e637bc77132e8c"/>
<approved hash="18,29,bd3c6955a2597630"/>
<approved hash="18,29,175ecc39c64ef979"/>
<approved hash="18,29,b0be65b047b392bd"/>
<approved hash="18,29,3627deb4705a3065"/>
<approved hash="18,29,50a28e07ef0b31ae"/>
<approved hash="18,29,c86a0c48639243e0"/>
<approved hash="18,29,2aedc8b8b157fb2f"/>
<approved hash="18,29,e816d344b8458317"/>
<approved hash="18,29,ffbb9b03b91ddda5"/>
<approved hash="18,29,3b836515aa785c42"/>
<approved hash="18,29,91c4c519ddf82108"/>
<approved hash="18,29,e417c9bea2b88f11"/>
<approved hash="18,29,5c01e05544425c46"/>
<approved hash="18,29,5594e704d1046394"/>
<approved hash="18,29,fb575846d9fcdebd"/>
<approved hash="18,29,5b7f1ec39ec3db7f"/>
<approved hash="18,29,3aa63240d940d1a6"/>
<approved hash="18,29,adf85a514f51b8f8"/>
<approved hash="18,29,70476d3adb3bc646"/>
<approved hash="18,29,c994cb4de94ceb95"/>
<approved hash="18,29,e1968483a67fc36a"/>
<approved hash="18,29,e23b8e7eac7bc03e"/>
<approved hash="18,29,46773ba1bb5dc68b"/>
<approved hash="18,29,f81a315cb158781e"/>
<approved hash="18,29,7f86ca18e1e75479"/>
<approved hash="18,29,1230c4e5efe03935"/>
<approved hash="18,29,c928b383a67fdcd4"/>
<approved hash="18,29,c05eb97eac7bd55b"/>
<approved hash="18,29,7f874305c8fbf479"/>
<approved hash="18,29,f95eca1ac1e4f2a0"/>
<approved hash="18,29,d73e83e98814dcc3"/>
<approved hash="18,29,8e89d3b253ce0ef5"/>
<approved hash="18,29,515916bc54c01325"/>
<approved hash="18,29,633d5687d684e33e"/>
<approved hash="18,29,7c2752f3fdf0d324"/>
<approved hash="18,29,416d09ad02a04a60"/>
<approved hash="18,29,13aba59a259593a4"/>
<approved hash="18,29,d66685a305ae566b"/>
<approved hash="18,29,0cb1a730113fbabe"/>
<approved hash="18,29,2ebf7620c02498bb"/>
<approved hash="18,29,31a5748af48eb1a1"/>
<approved hash="18,29,2ebc036c836baebb"/>
<approved hash="18,29,624855628465b34f"/>
<approved hash="18,29,8fb019dd37c6a1ab"/>
<approved hash="18,29,5c5884c7cedb1644"/>
<approved hash="18,29,94f251ddd1c114ee"/>
<approved hash="18,29,0ac4d22dc92c11c5"/>
<approved hash="18,29,9066c5474e451b64"/>
<approved hash="18,29,09ac52fdd2ff89ae"/>
<approved hash="18,29,0841526bd217883d"/>
<approved hash="18,29,ce129575d7098c6e"/>
<approved hash="18,29,faefd1ba7eb955ec"/>
<approved hash="18,29,e1e5d54e554d61e6"/>
<approved hash="18,29,50ae047a8477d0a3"/>
<approved hash="18,29,c0548a648169cb59"/>
<approved hash="18,29,c0141875f8682009"/>
<approved hash="18,29,c618197f1762c805"/>
<approved hash="18,29,a87482b502b22873"/>
<approved hash="18,29,fd00d6ab07ac2c07"/>
<approved hash="18,29,6b5384da8ec5614c"/>
<approved hash="18,29,f81df183f293fb0d"/>
<approved hash="18,29,6e57e865e81c6e2e"/>
<approved hash="18,29,723cfbfefb877245"/>
<approved hash="18,29,fbf175c375bafb88"/>
<approved hash="18,29,f468622a6253f411"/>
<approved hash="18,29,4185cf97cfee41fc"/>
<approved hash="18,29,9f539993bf7e2057"/>
<approved hash="18,29,bbc139d38c62cfd6"/>
<approved hash="18,29,f0086bf5b82cf02c"/>
<approved hash="18,29,8158121b254d8b02"/>
<approved hash="18,29,37a63ea6c17685aa"/>
<approved hash="18,29,bbc139d38c62cfd6"/>
<approved hash="18,29,6df236556ed7528a"/>
<approved hash="18,29,1eba241e94e85c7a"/>
<approved hash="18,29,ed97bdfdc4e0948a"/>
<approved hash="18,29,7bb826f1c6ec9ba5"/>
<approved hash="18,29,5a44e847687cda7f"/>
<approved hash="18,29,5a408932db0d087f"/>
<approved hash="18,29,72d03494dc909ad4"/>
<approved hash="18,29,c9627becfbed4963"/>
<approved hash="18,29,ceb1733ff33e4eb0"/>
<approved hash="18,29,5b4663bbe3badb47"/>
<approved hash="18,29,545c648de48cd45d"/>
<approved hash="18,29,021f8d818cf5036b"/>
<approved hash="18,29,5e3e28db62c51420"/>
<approved hash="18,29,cda92f5f2f43ca1d"/>
<approved hash="18,29,ce022a370957569e"/>
<approved hash="6,1,ea76c719470e6a61"/>
<approved hash="6,1,09ca9683e6ee6c58"/>
<approved hash="6,1,25cd969a78f5fe5c"/>
<approved hash="6,1,d9cf96feda93885c"/>
<approved hash="6,1,f33b25a3a683d403"/>
<approved hash="6,16,ea76c719470e6a61"/>
<approved hash="6,16,09ca9683e6ee6c58"/>
<approved hash="6,16,25cd969a78f5fe5c"/>
<approved hash="6,16,d9cf96feda93885c"/>
<approved hash="6,1,28a8851ea2a3f526"/>
<approved hash="6,16,28a8851ea2a3f526"/>
<approved hash="18,29,1fdaba421d6338a6"/>
<approved hash="18,29,eb9474888237adf1"/>
<approved hash="18,29,bf68fd63fd63bf68"/>
<approved hash="18,29,aea28ef00877973f"/>
<approved hash="18,29,86e61632c19a601b"/>
<approved hash="18,29,cbc7f1daf1dacbc7"/>
<approved hash="18,29,31947baf7baf3194"/>
<approved hash="18,29,586a027d027d586a"/>
<approved hash="18,29,4df30e060e064df3"/>
<approved hash="18,29,c63e84318431c63e"/>
<approved hash="18,29,46e62378216e44f0"/>
<approved hash="18,29,4de51f00b507e7e2"/>
<approved hash="18,29,6a7e3e22be25ea79"/>
<approved hash="18,29,fce20907a30556e0"/>
<approved hash="18,29,db792825a8275b7b"/>
<approved hash="18,29,9a5ebe05143b3060"/>
<approved hash="18,29,bdc59f271f193dfb"/>
<approved hash="18,29,8ed127a1bcae631b"/>
<approved hash="18,29,b8932eeabfa6cf86"/>
<approved hash="18,29,989f0c9bbb55e919"/>
<approved hash="18,29,8ec70eb664d21b80"/>
<approved hash="18,29,03351f6f928168aa"/>
<approved hash="18,29,65d65f5e07e26e18"/>
<approved hash="18,29,80dad422be25eadd"/>
<approved hash="18,29,31ddc225a8275bdf"/>
<approved hash="18,29,a2df75271f1ac8e2"/>
<approved hash="18,29,50e2e41a8e1c3ae4"/>
<approved hash="18,29,c9663bee6c5249a8"/>
<approved hash="18,29,81c057f592663a51"/>
<approved hash="18,29,675c344d224a715b"/>
<approved hash="18,29,d65b224a3448c059"/>
<approved hash="18,29,4559954883755364"/>
<approved hash="18,29,463561d7e215f413"/>
<approved hash="18,29,b76404751273a162"/>
<approved hash="18,29,54c5aa5985142ac5"/>
<approved hash="18,29,c38a62397f8929ad"/>
<approved hash="18,29,7212ad4c37feb60d"/>
<approved hash="18,29,ca4c4faea59df1da"/>
<approved hash="18,29,65d45bc95bc965d4"/>
<approved hash="18,29,87b3823186741ce0"/>
<approved hash="18,29,69b3f2b388ce8318"/>
<approved hash="18,29,117b57705770117b"/>
<approved hash="18,29,e3e0a415a415e3e0"/>
<approved hash="18,29,682d2e222e22682d"/>
<approved hash="18,29,f679a86ea86ef679"/>
<approved hash="18,29,9f87d1bcd1bc9f87"/>
<approved hash="18,29,ce61dd7cdd7cce61"/>
<approved hash="18,29,40e1ce61bd746b80"/>
<approved hash="18,29,d733b40eb40ed733"/>
<approved hash="18,29,59b3d733a4466b80"/>
<approved hash="18,29,2e1b209b53efeb80"/>
<approved hash="18,29,2e1b209b53efeb80"/>
<approved hash="18,29,344ebacec99b6b80"/>
<approved hash="18,29,baced1c5d1c5bace"/>
<approved hash="18,29,46d548553b21eb80"/>
<approved hash="18,29,46d548553b21eb80"/>
<approved hash="18,29,c398a897a897c398"/>
<approved hash="18,29,4d18c398b0ed6b80"/>
<approved hash="18,29,534c5dcc2e9aeb80"/>
<approved hash="18,29,534c5dcc2e9aeb80"/>
<approved hash="18,29,3ab234324748eb80"/>
<approved hash="18,29,3ab234324748eb80"/>
<approved hash="18,29,dc12229940faa790"/>
<approved hash="18,29,bfab575ad48634b6"/>
<approved hash="18,29,116eb8afe9baccc0"/>
<approved hash="18,29,08163586fe62a9c0"/>
<approved hash="18,29,45e28bf335cde004"/>
<approved hash="18,29,14e932721bbeaa40"/>
<approved hash="18,29,fc9772a0cb15876b"/>
<approved hash="18,29,c731bfafb96ac1f4"/>
<approved hash="18,29,684fefb6efb7684e"/>
<approved hash="18,29,e0f2769f9d9e0bf3"/>
<approved hash="18,29,2bc86b98edec64a5"/>
<approved hash="18,29,8e27d40c420b1820"/>
<approved hash="18,29,557b3898b8f1aeba"/>
<approved hash="18,29,f4fb83d436444f21"/>
<approved hash="18,29,aeb1182998292eb1"/>
<approved hash="18,29,4d94febe7ec2cde8"/>
<approved hash="18,29,a5ed780779086a7f"/>
<approved hash="18,29,0a63e4c364c48a64"/>
<approved hash="18,29,e65aefb6efc8e624"/>
<approved hash="18,29,6ee768969ee89899"/>
<approved hash="18,29,e6267da17da3e624"/>
<approved hash="18,29,fe6c43a8d6d66b12"/>
<approved hash="18,29,6e9be4880f8a8599"/>
<approved hash="18,29,62ebfe73950e0996"/>
<approved hash="18,29,cb92590a3204a09c"/>
<approved hash="18,29,82401fdc0aa1973d"/>
<approved hash="18,29,7ebccb20de266bba"/>
<approved hash="18,29,afb28c3f673144bc"/>
<approved hash="18,29,2b39b8a5adab3e37"/>
<approved hash="18,29,1a3bf1b61aa9f124"/>
<approved hash="18,29,4e24e52e8e21252b"/>
<approved hash="18,29,dfea79756c7acae5"/>
<approved hash="18,29,115f88e408e6915d"/>
<approved hash="18,29,01d59686038494d7"/>
<approved hash="18,29,a4b2d5dc55a024ce"/>
<approved hash="18,29,b5b653ebaef7a7c6"/>
<approved hash="18,29,6bb58629aecfa752"/>
<approved hash="18,29,f5302709a70d7534"/>
<approved hash="18,29,fe3e2c17ac137e3a"/>
<approved hash="18,29,43eeafaf2facc3ed"/>
<approved hash="18,29,6ab7f3ed18e281b8"/>
<approved hash="18,29,b642f8586d54234e"/>
<approved hash="18,29,afb0e8d603da44bc"/>
<approved hash="18,29,f1892b0083bd2a47"/>
<approved hash="18,29,ac8bf8739276c68e"/>
<approved hash="18,29,dd8e9676fc68b790"/>
<approved hash="18,29,4e901968736a2492"/>
<approved hash="18,29,7c93886be26d1695"/>
<approved hash="18,29,d519379f782d85d7"/>
<approved hash="18,29,382dc93385921f78"/>
<approved hash="18,29,81ce27aace383e5f"/>
<approved hash="18,29,4b0d181c0e195d08"/>
<approved hash="18,29,3a08761960072c16"/>
<approved hash="18,29,a916f907ef05bf14"/>
<approved hash="18,29,4cc5a8a4ea798c54"/>
<approved hash="18,29,9b1568047e028d13"/>
<approved hash="18,29,e4ba6628496b3ecb"/>
<approved hash="18,29,03c9e138742796d6"/>
<approved hash="18,29,aebc2e0dc51345a2"/>
<approved hash="18,29,2b39b8a5adab3e37"/>
<approved hash="18,29,1a3bf1b61aa9f124"/>
<approved hash="18,29,0dbbe52e8e2d66b8"/>
<approved hash="18,29,9c7579756c768976"/>
<approved hash="18,29,a877f0786e7c3673"/>
<approved hash="18,29,b37df74377473379"/>
<approved hash="18,29,f9941875f8691988"/>
<approved hash="18,29,ff98197f1763f184"/>
<approved hash="18,29,1e3bdf9b5a1e4952"/>
<approved hash="18,29,f635ed1f4b7a13e9"/>
<approved hash="18,29,23d384da8ec429cd"/>
<approved hash="18,29,89bc1875f86e69a7"/>
<approved hash="18,29,8fb01a95b48e21ab"/>
<approved hash="18,29,1fadb633abc90257"/>
<approved hash="18,29,6edddbdf623b7d90"/>
<approved hash="18,29,902f1e03f2afd62a"/>
<approved hash="18,29,ce0db660c214e73f"/>
<approved hash="18,29,e5e81802b248f5d8"/>
<approved hash="18,29,3a006464a4b24c20"/>
<approved hash="18,29,ad61effe203e2db7"/>
<approved hash="18,29,ff40f6def3d5fa4b"/>
<approved hash="18,29,96224f93bb9e881d"/>
<approved hash="18,29,84f2bab545464e40"/>
<approved hash="18,29,41cbdecaa490f26f"/>
<approved hash="18,29,e51f3aef2ec3763c"/>
<approved hash="18,29,5158a3782dd649db"/>
<approved hash="18,29,d05f013df1979158"/>
<approved hash="18,29,9864a4d1753a32c2"/>
<approved hash="18,29,39d38c62b6d6bbad"/>
<approved hash="18,29,54db1549f00b817c"/>
<approved hash="18,29,36919280848f209e"/>
<approved hash="18,29,30018bf80bf7b00e"/>
<approved hash="18,29,d87d6cf206fdb272"/>
<approved hash="18,29,4e299bc31bc1ce2b"/>
<approved hash="18,29,369c92ae12acb69e"/>
<approved hash="18,29,57d50220e821bdd4"/>
<approved hash="18,29,6c481e3f5fc95d84"/>
<approved hash="18,29,e40787617d46e60f"/>
<approved hash="18,29,3e16291da05f95dc"/>
<approved hash="18,29,3f31ce09ccca3680"/>
<approved hash="18,29,39fa9467b97049fb"/>
<approved hash="18,29,5a43a7c027fcda7f"/>
<approved hash="18,29,5b42127ffbf1cf3d"/>
<approved hash="18,29,bf0d77f648aedffe"/>
<approved hash="18,29,f24ef6d0f5dcf142"/>
<approved hash="18,29,4a503494dc93a257"/>
<approved hash="18,29,f6303bbebbbd7633"/>
<approved hash="18,29,f1e3336db36e71e0"/>
<approved hash="18,29,63c73b3abb39e3c4"/>
<approved hash="18,29,6cdd3c0cbc0fecde"/>
<approved hash="18,29,959bc9a5ce5c9262"/>
<approved hash="18,29,a66a6c3562bc85b7"/>
<approved hash="18,29,995f8c62cfc2dc21"/>
<approved hash="18,29,74cbc019798dacd0"/>
<approved hash="18,29,dc1b21b3ed86cf27"/>
<approved hash="18,29,74c523b933c5f330"/>
<approved hash="18,29,74cf381e888a2ed0"/>
<approved hash="18,29,bac1977229cfcfd6"/>
<approved hash="18,29,341f186e98325619"/>
<approved hash="18,29,c0192e1cb224a21b"/>
<approved hash="18,29,e0dffafa94e85cbf"/>
<approved hash="18,29,3c02bcc10906f4cb"/>
<approved hash="18,29,833958921e95d4eb"/>
<approved hash="18,29,2ac1aac1ff44ecc5"/>
<approved hash="18,29,e417d435b2197c11"/>
<approved hash="18,29,52e231567eda5b83"/>
<approved hash="18,29,226fde8d6449428d"/>
<approved hash="18,29,2464789a692ac29e"/>
<approved hash="18,29,9e6c2c130b0f6aac"/>
<approved hash="18,29,ef723398540fed60"/>
<approved hash="18,29,7c47b1c5a4d4e826"/>
<approved hash="18,29,4a0cf39fe3aa52b5"/>
<approved hash="18,29,32d162e01d67a091"/>
<approved hash="18,29,f5736a11f6f182ba"/>
<approved hash="18,29,b6057331f661b117"/>
<approved hash="18,29,0db524f0a1568263"/>
<approved hash="18,29,1c3a047d02a0bc9f"/>
<approved hash="18,29,d17a8262947fc767"/>
<approved hash="18,29,6067907f867d7665"/>
<approved hash="18,29,ef65237d357af962"/>
<approved hash="18,29,0162b27aa4781760"/>
<approved hash="18,29,0b2c21f41a46e3e0"/>
<approved hash="18,29,031935c2f900b4d9"/>
<approved hash="18,29,c5bccecda91c5d7e"/>
<approved hash="18,29,8a9aea63f015c0a0"/>
<approved hash="18,29,2615e32ee396d97e"/>
<approved hash="18,29,3e9562e408f95488"/>
<approved hash="18,29,8f8870f91afbe58a"/>
<approved hash="18,29,008ac3fba9fc6a8d"/>
<approved hash="18,29,1247db4de772858c"/>
<approved hash="18,29,ee8d52fc38fe848f"/>
<approved hash="18,29,ae56d8c302f2c265"/>
<approved hash="18,29,c095d3c7dcb19310"/>
<approved hash="18,29,0480e0c7a2ee58c7"/>
<approved hash="18,29,19be28db62c453a1"/>
<approved hash="18,29,bb6e2875920ca8bd"/>
<approved hash="18,29,bbf80b06eb850b86"/>
<approved hash="18,29,7d1080e5b7431161"/>
<approved hash="18,29,639d0cd49a979361"/>
<approved hash="18,29,181e4ab3a8b5fa18"/>
<approved hash="18,29,15da4acf2cc973dc"/>
<approved hash="18,29,11fea7190103b7e4"/>
<approved hash="18,29,985e8621bfab8b4c"/>
<approved hash="18,29,11e24657a651f1e4"/>
<approved hash="18,29,17ee44aba4adf7e8"/>
<approved hash="18,29,1f3e4c9bac9dff38"/>
<approved hash="18,29,2102708626807704"/>
<approved hash="18,29,b2dce45611a26ab0"/>
<approved hash="18,29,231670e390e5c310"/>
<approved hash="18,29,19324e87ae81f934"/>
<approved hash="18,29,1d2a72ef92e9fd2c"/>
<approved hash="18,29,19b1092f14ca0454"/>
<approved hash="18,29,f45f5a9212a23a30"/>
<approved hash="18,29,368fb2ec0e82eaed"/>
<approved hash="18,29,23f1df529af3ec78"/>
<approved hash="18,29,2b280ec20efb4b72"/>
<approved hash="18,29,beb99a2829c4e2f7"/>
<approved hash="18,29,fed8f746f5c9fc57"/>
<approved hash="18,29,83c739648f6835cb"/>
<approved hash="18,29,84c921e6a1ea04c5"/>
<approved hash="18,29,4ba3b7ca15cee9a7"/>
<approved hash="18,29,6d1e991baf1f5b1a"/>
<approved hash="18,29,33a69fd93d25915a"/>
<approved hash="18,29,38347f70da769d32"/>
<approved hash="18,29,1992616ee1689994"/>
<approved hash="18,29,320cd5b980bd6708"/>
<approved hash="18,29,102ccceffcea2029"/>
<approved hash="18,29,a54647f1c7f42543"/>
<approved hash="18,29,fa8dd202d907f188"/>
<approved hash="18,29,e597d05350566592"/>
<approved hash="18,29,5a65ed6f0c6abb60"/>
<approved hash="18,29,60d129d42f28662d"/>
<approved hash="18,29,65ef15cc9530e513"/>
<approved hash="18,29,e9101c3c773c8210"/>
<approved hash="18,29,8813b24b27b71def"/>
<approved hash="18,29,99a1a0f14b0d725d"/>
<approved hash="18,29,ebcd46f7c60b6b31"/>
<approved hash="18,29,0da6bc0c3c0f8da5"/>
<approved hash="18,29,56ea521343d996a2"/>
<approved hash="18,29,be912b964068d56f"/>
<approved hash="18,29,52ecc7ebacec39eb"/>
<approved hash="18,29,ff68d9db4cd56a66"/>
<approved hash="18,29,676b906cfb610c66"/>
<approved hash="18,29,3be6ace1c7e250e5"/>
<approved hash="18,29,d693c470a10d10fe"/>
<approved hash="18,29,6ae1d0217ceeabd2"/>
<approved hash="18,29,eedacb61206f05d4"/>
<approved hash="18,29,f9ed0e64dd40a71c"/>
<approved hash="18,29,3341d59bc6c9b9e5"/>
<approved hash="18,29,840028d93d2591fc"/>
<approved hash="18,29,9d70d222c7218873"/>
<approved hash="18,29,7d65be78e57a2667"/>
<approved hash="18,29,7d645800ae038b67"/>
<approved hash="18,29,785b8199019bf859"/>
<approved hash="18,29,785a6705e706f859"/>
<approved hash="18,29,9aead0cddbce91e9"/>
<approved hash="18,29,59bd95d19ed252be"/>
<approved hash="18,29,46a0d091b2ee26e5"/>
<approved hash="18,29,fd8468094d09d884"/>
<approved hash="18,29,5d2bf6177617dd2b"/>
<approved hash="18,29,e46c3f094d0c9669"/>
<approved hash="18,29,113ef6177612913b"/>
<approved hash="18,29,6d772abc0dccb283"/>
<approved hash="18,29,8ec638bf22ba94c3"/>
<approved hash="18,29,113e99a119a4913b"/>
<approved hash="18,29,32b7b231294a8a2e"/>
<approved hash="18,29,36baf70a0245ffd1"/>
<approved hash="18,29,ffc56de61dd381ef"/>
<approved hash="18,29,123515e61dd38135"/>
<approved hash="18,29,38b049f17cdadfed"/>
<approved hash="18,29,c642720dbba2e311"/>
<approved hash="18,29,bb53ed881de2c340"/>
<approved hash="18,29,b22b8c3a173a56db"/>
<approved hash="18,29,3d7ed916dd2d376f"/>
<approved hash="18,29,873f504cf01b4176"/>
<approved hash="18,29,25221046bab8d93a"/>
<approved hash="18,29,2f0ab3101852d18e"/>
<approved hash="18,29,04796a95626bc046"/>
<approved hash="18,29,f70527fbe65bf699"/>
<approved hash="18,29,695fb3af28af521b"/>
<approved hash="18,29,7cf82649bd49d21b"/>
<approved hash="18,29,8e6254f2cff2521b"/>
<approved hash="18,29,95b6cf075407d21b"/>
<approved hash="18,29,8851d2ae49aed21b"/>
<approved hash="18,29,820d589dc39d521b"/>
<approved hash="18,29,6f6335f0aef0d21b"/>
<approved hash="18,29,76b4ac043704521b"/>
<approved hash="18,29,e860c39dc39de860"/>
<approved hash="18,29,8851d2ae49aed21b"/>
<approved hash="18,29,7cf82649bd49d21b"/>
<approved hash="18,29,140b37043704140b"/>
<approved hash="18,29,fcf9cff2cff2fcf9"/>
<approved hash="18,29,95b6cf075407d21b"/>
<approved hash="18,29,6f6335f0aef0d21b"/>
<approved hash="18,29,03b228af28af03b2"/>
<approved hash="18,29,e9e6d7f3d7f3e9e6"/>
<approved hash="18,29,1a7dc44ac44a1a7d"/>
<approved hash="18,29,9c2aff26c46387ba"/>
<approved hash="18,29,5484acb8062b2eed"/>
<approved hash="18,29,93b15dbe5dbe93b1"/>
<approved hash="18,29,7b43a548a5487b43"/>
<approved hash="18,29,6fdaa927a9276fda"/>
<approved hash="18,29,e50f23142314e50f"/>
<approved hash="18,29,2fb20bc0d14b2bc3"/>
<approved hash="18,29,3b82c0a28a66e01b"/>
<approved hash="18,29,2183ef43c0709efc"/>
<approved hash="18,29,644ac2910223d385"/>
<approved hash="18,29,fd89ae91b8aeebb6"/>
<approved hash="18,29,8cb6bcaeaaac9ab4"/>
<approved hash="18,29,1bb44fac59aa0db2"/>
<approved hash="18,29,2db1dea9c8a73bbf"/>
<approved hash="18,29,b55598b302eef223"/>
<approved hash="18,29,12664e1724287859"/>
<approved hash="18,29,63595c28362a095b"/>
<approved hash="18,29,f45baf2ac52c9e5d"/>
<approved hash="18,29,f14677269a6f993e"/>
<approved hash="18,29,c25e3e2f5421a850"/>
<approved hash="18,29,397f5ff5c9920ee4"/>
<approved hash="18,29,9e77815157514877"/>
<approved hash="18,29,8994ac307a325f96"/>
<approved hash="18,29,8cb6a88b28890cb4"/>
<approved hash="18,29,1bb44e48ce4e9bb2"/>
<approved hash="18,29,1e964af39cf5c890"/>
<approved hash="18,29,2db1df4d5f43adbf"/>
<approved hash="18,29,2893dbf60df8fe9d"/>
<approved hash="18,29,35604289d60f551c"/>
<approved hash="18,29,5914ca97de37b103"/>
<approved hash="18,29,fbba175d0950fd49"/>
<approved hash="18,29,ed6b7e51a85f3b65"/>
<approved hash="18,29,4221cdbfcebf4121"/>
<approved hash="18,29,359b50830048d180"/>
<approved hash="18,29,04f67a7290960f04"/>
<approved hash="18,29,35922812d827f880"/>
<approved hash="18,29,2d79049ebde75515"/>
<approved hash="18,29,2c66d5ac33f2b41d"/>
<approved hash="18,29,c5ac4bbadceda356"/>
<approved hash="18,29,03f2b9e7b9e703f2"/>
<approved hash="18,29,79a533aa33aa79a5"/>
<approved hash="18,29,12afaeafc8fe8408"/>
<approved hash="18,29,f069aa5eaa5ef069"/>
<approved hash="18,29,834fc30ddb4465f0"/>
<approved hash="18,29,9157cb5ccb5c9157"/>
<approved hash="18,29,0f1b4d004d000f1b"/>
<approved hash="18,29,85cec733c73385ce"/>
<approved hash="18,29,cb9202607aeab3dd"/>
<approved hash="6,1,478b9f939dd245ca"/>
<approved hash="6,1,9cde8e2531bbad7e"/>
<approved hash="6,1,f33b2b32a812d403"/>
<approved hash="19,1,660c1792143c65a2"/>
<approved hash="19,1,6788161613fc6262"/>
<approved hash="19,1,a789921797fba265"/>
<approved hash="19,1,a60d9393903ba5a5"/>
<approved hash="18,29,6c097da67f447003"/>
<approved hash="18,29,01d52403a40081d6"/>
<approved hash="18,29,7bd82e0eae0bfbdd"/>
<approved hash="18,29,918c10610562848f"/>
<approved hash="18,29,0a81c2e942eb8a83"/>
<approved hash="18,29,01d43914b91681d6"/>
<approved hash="18,29,eb8140f355f6fe84"/>
<approved hash="18,29,7bd82e0eae0bfbdd"/>
<approved hash="18,29,708dd5f355f6f088"/>
<approved hash="18,29,9460a0f420f51461"/>
<approved hash="18,29,9f355b09db081f34"/>
<approved hash="18,29,bdae722053eae1bf"/>
<approved hash="18,29,e42665738e4e0f1b"/>
<approved hash="18,29,a3433cfb57f9c841"/>
<approved hash="18,29,0c4595fdfef2674a"/>
<approved hash="18,29,e67c6a57ff54737f"/>
<approved hash="18,29,30231f9774a95b1d"/>
<approved hash="18,29,432ed452c150562c"/>
<approved hash="18,29,3fad88d19dd72aab"/>
<approved hash="18,29,a59b822fe921ce95"/>
<approved hash="18,29,ec287d54685bf927"/>
<approved hash="18,29,d6337d0ffd0b5637"/>
<approved hash="18,29,8672d42f5e7dadc7"/>
<approved hash="18,29,c68782a797b9d399"/>
<approved hash="18,29,56cf1f84749a3dd1"/>
<approved hash="18,29,302179b6928adb1d"/>
<approved hash="18,29,21536bc8fef4b46f"/>
<approved hash="18,29,c0675452c1505565"/>
<approved hash="18,29,bce408d19dd729e2"/>
<approved hash="18,29,a59b80e76be94e95"/>
<approved hash="18,29,6f61fd54685bfa6e"/>
<approved hash="18,29,b4e99299079721e7"/>
<approved hash="18,29,201fd8a133abcb15"/>
<approved hash="18,29,78e6fe8b158993e4"/>
<approved hash="18,29,f05b67a267a0f059"/>
<approved hash="18,29,e79f878ae2956a9f"/>
<approved hash="18,29,26a5903d103ea6a6"/>
<approved hash="18,29,c58166abe6ae4584"/>
<approved hash="18,29,b5ef587b690e7a7e"/>
<approved hash="18,29,82106cb0ecb00210"/>
<approved hash="18,29,e6f3e082168410f5"/>
<approved hash="18,29,6e4e67a267a46e48"/>
<approved hash="18,29,4c548de2ddb265e5"/>
<approved hash="18,29,e6f66ce587e60df5"/>
<approved hash="18,29,6e4bf5ccf5cf6e48"/>
<approved hash="18,29,59d6c6be6cc19a70"/>
<approved hash="18,29,3ca76dc9edcdbca3"/>
<approved hash="18,29,c5b433e9cef4d7c5"/>
<approved hash="18,29,f88c0340bb61a24d"/>
<approved hash="18,29,bbb2664106d8ff2a"/>
<approved hash="18,29,73bb83930393f3bb"/>
<approved hash="18,29,6a488ac40ac4ea48"/>
<approved hash="18,29,78ee786ef86ef8ee"/>
<approved hash="18,29,7d43af7a2f79fd40"/>
<approved hash="18,29,764da4642467f64e"/>
<approved hash="18,29,ac3177a513cae2bd"/>
<approved hash="18,29,279d16031292230c"/>
<approved hash="18,29,db0eef5f6f505b01"/>
<approved hash="18,29,1251e95211f81342"/>
<approved hash="18,29,2000e9dc7fd3b60f"/>
<approved hash="18,29,db9ad7db57d85b99"/>
<approved hash="18,29,2d521672967ead5e"/>
<approved hash="18,29,fdfe69774c8d1e3c"/>
<approved hash="18,29,d0087807e6084e07"/>
<approved hash="18,29,cb027f3cff334b0d"/>
<approved hash="18,29,01e1a0004005e1e4"/>
<approved hash="18,29,07eda10aaf0f09e8"/>
<approved hash="18,29,0e3cff9e3a1bd951"/>
<approved hash="18,29,9fbd3b23341d9083"/>
<approved hash="18,29,db73c5862d833376"/>
<approved hash="18,29,6752a91d291ce753"/>
<approved hash="18,29,6ee7a26e226feee6"/>
<approved hash="18,29,f0c48898089970c5"/>
<approved hash="18,29,fdce8d8e0d8f7dcf"/>
<approved hash="18,29,55d5ff456a4ac0da"/>
<approved hash="18,29,bd2bc1cf54cd2829"/>
<approved hash="18,29,6633fd185b0e9be1"/>
<approved hash="18,29,bb25a835283b3b2b"/>
<approved hash="18,29,6c2af014f0156c2b"/>
<approved hash="18,29,402bae4cfc421225"/>
<approved hash="18,29,aba70cae06a9a1a0"/>
<approved hash="18,29,56aed1d551a9d6d2"/>
<approved hash="18,29,ada0d473a40fdddc"/>
<approved hash="18,29,fac99a35abfce92c"/>
<approved hash="18,29,11c9a000407af1b3"/>
<approved hash="18,29,17c5a2e00c9ab9bf"/>
<approved hash="18,29,6fb3a62dbbd3724d"/>
<approved hash="18,29,1eddcbb2ca56a591"/>
<approved hash="18,29,802e6e6e2ac27e2a"/>
<approved hash="18,29,b60db661c215e72b"/>
<approved hash="18,29,15eb0801b248e5d8"/>
<approved hash="18,29,c233ec485c9ec413"/>
<approved hash="18,29,554d77e9d829a59b"/>
<approved hash="18,29,6f4e46d043db6a45"/>
<approved hash="18,29,c6236f8f938c601b"/>
<approved hash="18,29,841e32a13d523640"/>
<approved hash="18,29,61cb9e3c0c654a6f"/>
<approved hash="18,29,56ad1ac09abfd6d2"/>
<approved hash="18,29,ada31f8d09f2bbdc"/>
<approved hash="18,29,5158a36f95c1f1db"/>
<approved hash="18,29,d05f012a49802958"/>
<approved hash="18,29,ae860a971c93b882"/>
<approved hash="18,29,b81503ec83e83811"/>
<approved hash="18,29,5069e4e68ee23a6d"/>
<approved hash="18,29,59196bdb7dc74f05"/>
<approved hash="18,29,8c839e41884d9a8f"/>
<approved hash="18,29,b00dd2cfc4cba609"/>
<approved hash="18,29,e7b605741371f1b3"/>
<approved hash="18,29,2b3039f22ffe3d3c"/>
<approved hash="18,29,63770adc68cfff78"/>
<approved hash="18,29,00492cc4fd2522ed"/>
<approved hash="18,29,81ff04570ed6bb98"/>
<approved hash="18,29,fcc53548d00a4157"/>
<approved hash="18,29,1c1bb6701b77f879"/>
<approved hash="18,29,d63413de93dd5637"/>
<approved hash="18,29,ae811ab39ab02e82"/>
<approved hash="18,29,dc40fbd179d75e46"/>
<approved hash="18,29,bd0f0cd81adcab0b"/>
<approved hash="18,29,d046e7d765d55244"/>
<approved hash="18,29,a444d3d551db264a"/>
<approved hash="18,29,b84adfdb5dd93a48"/>
<approved hash="18,29,8c48cbd949df0e4e"/>
<approved hash="18,29,804eb7df35dd024c"/>
<approved hash="18,29,944ca3dd21c31652"/>
<approved hash="18,29,6852afc32dc2ea53"/>
<approved hash="18,29,7c509bc119c0fe51"/>
<approved hash="18,29,705687c705c6f257"/>
<approved hash="18,29,ee9b73c6f1c56c98"/>
<approved hash="18,29,dfc88a3d603e35cb"/>
<approved hash="18,29,e100d7512897e2da"/>
<approved hash="18,29,711591a291848929"/>
<approved hash="18,29,e8dcb9bbf3b6a2d1"/>
<approved hash="18,29,5569fda797a63f68"/>
<approved hash="18,29,c26201bf59be9a63"/>
<approved hash="18,29,371e8fe5b08257d2"/>
<approved hash="18,29,2e46e418ea900d84"/>
<approved hash="18,29,0173045777f65414"/>
<approved hash="18,29,74ff582ef1b934d0"/>
<approved hash="18,29,5428b9807589df1b"/>
<approved hash="18,29,74fabb854bf98b30"/>
<approved hash="18,29,74fcb03200b9a6d0"/>
<approved hash="18,29,32f62f5ea1fa77e2"/>
<approved hash="18,29,4c2c905d10062e2d"/>
<approved hash="18,29,582ea62b3a103a2f"/>
<approved hash="18,29,78eb72c60cd5d48b"/>
<approved hash="18,29,a43124fd9106f4f8"/>
<approved hash="18,29,1b05d0a186a15cd7"/>
<approved hash="18,29,52fdd2fe4744ecf9"/>
<approved hash="18,29,7c2b5c093a2de425"/>
<approved hash="18,29,62e231550ed94b80"/>
<approved hash="18,29,0276fe886478ea8a"/>
<approved hash="18,29,5c51f0a611164aaa"/>
<approved hash="18,29,0659b42f8332e290"/>
<approved hash="18,29,574ebbabdc3c755c"/>
<approved hash="18,29,e47429f01ce0901a"/>
<approved hash="18,29,22316b9ec3ab5288"/>
<approved hash="18,29,8aee1ae30d6480ad"/>
<approved hash="18,29,6d4ee2258edd0a8f"/>
<approved hash="18,29,2e32eb058e550923"/>
<approved hash="18,29,b598bcc529653a70"/>
<approved hash="18,29,fee74924dc2b6be8"/>
<approved hash="18,29,7e62ef4c844c1562"/>
<approved hash="18,29,7b26bdc2d900a4e6"/>
<approved hash="18,29,4d9166cda91c5d53"/>
<approved hash="18,29,1ae24399d6958fee"/>
<approved hash="18,29,08705217b91be37c"/>
<approved hash="18,29,02a69262f014c09d"/>
<approved hash="18,29,48a96bf4249d1b24"/>
<approved hash="18,29,acaf68c4c2ed58e8"/>
<approved hash="18,29,09edb8e8d3ea62ef"/>
<approved hash="18,29,256e546b3f6d4e68"/>
<approved hash="18,29,8d6b68fbfdc61856"/>
<approved hash="18,29,f0eb63ee08d19bd4"/>
<approved hash="18,29,8c543f515454e751"/>
<approved hash="18,29,d70dc411c32e616f"/>
<approved hash="18,29,c26aad823886576e"/>
<approved hash="18,29,9ff97975924874c4"/>
<approved hash="18,29,95d17a39ef3c00d4"/>
<approved hash="18,29,6be87c402f641518"/>
<approved hash="18,29,f50846bfd3bf6008"/>
<approved hash="18,29,abf81b3233b1d386"/>
<approved hash="18,29,ab6e38414a3870bd"/>
<approved hash="18,29,6d1090fb9770997f"/>
<approved hash="18,29,cbae94e63296d34d"/>
<approved hash="18,29,9713c4b62488772d"/>
<approved hash="18,29,9507fac21afc7539"/>
<approved hash="18,29,ab3bf8ce18f04b05"/>
<approved hash="18,29,911fc6aa26947121"/>
<approved hash="18,29,9033c29e20a0720d"/>
<approved hash="18,29,a92ff8abae95ff11"/>
<approved hash="18,29,b2dc647b898fe2b0"/>
<approved hash="18,29,99ca2f2d89163ff1"/>
<approved hash="18,29,185e860c3786134c"/>
<approved hash="18,29,99cfce7a2e4479f1"/>
<approved hash="18,29,9fc3cc862cb87ffd"/>
<approved hash="18,29,9df7c2e2a4dcfbc9"/>
<approved hash="18,29,c9b3492d54d6d448"/>
<approved hash="18,29,6c70f291f2a15a1f"/>
<approved hash="18,29,8ea33aed7e827ac1"/>
<approved hash="18,29,93eecf60e2c07479"/>
<approved hash="18,29,a305e6efe6d7c35e"/>
<approved hash="18,29,26aa3234f1d99ae5"/>
<approved hash="18,29,1bd0b1730774add7"/>
<approved hash="18,29,6ed6474845c76c59"/>
<approved hash="18,29,1cdea9f129f69cd9"/>
<approved hash="18,29,d3be3fd79dda71b3"/>
<approved hash="18,29,f5031106270bc30e"/>
<approved hash="18,29,bbb2e7cd45c919b6"/>
<approved hash="18,29,918fe973697d1181"/>
<approved hash="18,29,b029f76d52631527"/>
<approved hash="18,29,aa115da408a9ff1c"/>
<approved hash="18,29,1600c13011e6e0d8"/>
<approved hash="18,29,705f948560d384eb"/>
<approved hash="18,29,3d55cfe24fe0bd57"/>
<approved hash="18,29,62915a1e5113699c"/>
<approved hash="18,29,883f44fc74feb83d"/>
<approved hash="18,29,7d8b584fd842fd86"/>
<approved hash="18,29,d2796573847f3375"/>
<approved hash="18,29,18c4b1c1b7c41ec1"/>
<approved hash="18,29,1dfa8dd90ddc9dff"/>
<approved hash="18,29,26e842e4db2a5ea2"/>
<approved hash="18,29,63d93ee3bee7e3dd"/>
<approved hash="18,29,855234f8b4fc0556"/>
<approved hash="18,29,0c1450cd45c91910"/>
<approved hash="18,29,05845ad64fd51087"/>
<approved hash="18,29,f58906945d97ae8a"/>
<approved hash="18,29,f58820ecd6ee038a"/>
<approved hash="18,29,f0b73975b97670b4"/>
<approved hash="18,29,f0b61fe99feb70b4"/>
<approved hash="18,29,1206682163221905"/>
<approved hash="18,29,d1512d3d2621da4d"/>
<approved hash="18,29,3e4ca891d2ee4609"/>
<approved hash="18,29,7568e0e5c5fa5077"/>
<approved hash="18,29,d5c77efbfee455d8"/>
<approved hash="18,29,5c80b7e5c5f92e9c"/>
<approved hash="18,29,a9d27efbfee729ce"/>
<approved hash="18,29,b588424195317a7d"/>
<approved hash="18,29,362aa053ba4f2c36"/>
<approved hash="18,29,a9d2014d815129ce"/>
<approved hash="18,29,9a491a321949bad0"/>
<approved hash="18,29,36bbf7f67ab987d0"/>
<approved hash="6,1,078b5f935ddd05c5"/>
<approved hash="6,1,1cdb2ede71477d7d"/>
<approved hash="6,1,2b2a73c98810b4ef"/>
<approved hash="19,1,460d2793243445aa"/>
<approved hash="19,1,4789261723f4426a"/>
<approved hash="19,1,460fa391a03d45a3"/>
<approved hash="19,1,478ba215a7fd4263"/>
</errors>
</board>
</drawing>
</eagle>


text:
package main

import (
	"encoding/csv"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"reflect"
	"regexp"
	"time"

	"github.com/DusanKasan/parsemail"
	"github.com/ghodss/yaml"
	"github.com/kardianos/osext"
)

// config parser base struct
type config struct {
	categories struct {
		category []string
	}
}

// person object for dict
type person struct {
	email      string
	categories []string
	double     bool
}

// helper functions for array
func find(a []string, x string) int {
	for i, n := range a {
		if x == n {
			return i
		}
	}
	return len(a)
}
func remove(slice []string, s int) []string {
	return append(slice[:s], slice[s+1:]...)
}

// analyse E-Mail file (.eml)
func analyseFile(filePath string, persons map[string]person, finderConfig map[string]string) {
	file, err := os.Open(filePath)
	if err != nil {
		log.Fatal(err)
		return
	}
	defer file.Close()
	email, err := parsemail.Parse(file) // returns Email struct and error
	if err != nil {
		log.Println("could not parse email appropriately:", filePath)
	}

	var regexChecker map[string]*regexp.Regexp
	regexChecker = make(map[string]*regexp.Regexp)

	for fcK, fcV := range finderConfig {
		regexChecker[fcK] = regexp.MustCompile(`(?i)(` + fcV + `)`)
	}

	var mailAddress string
	if len(email.From) < 1 {
		mailAddress = "unknown"
		fmt.Printf("HEADER: %v", email.Header)
	} else {
		mailAddress = email.From[0].Address
	}
	for k, v := range regexChecker {
		match := v.MatchString(email.TextBody)
		if match == true {
			if val, ok := persons[mailAddress]; ok {
				if index := find(val.categories, "unmatched"); index < len(val.categories) {
					val.categories = remove(val.categories, index)
				}
				val.categories = append(val.categories, k)
				if len(val.categories) > 1 {
					val.double = true
				}
			} else {
				persons[mailAddress] = person{
					email:      mailAddress,
					categories: []string{k},
					double:     false,
				}
			}
		} else {
			if _, ok := persons[mailAddress]; !ok {
				persons[mailAddress] = person{
					email:      mailAddress,
					categories: []string{"unmatched"},
					double:     false,
				}
			}
		}
	}
}

func main() {
	startOutput := `
----------------------
- E-Mail Categorizer -
----------------------
`
	fmt.Print(startOutput)

	// get folder of execution or if in development, ignore it
	dir, err := osext.ExecutableFolder()
	if dir[0:4] == "/var" {
		dir = ""
	} else {
		dir += "/"
	}
	if err != nil {
		log.Fatal(err)
	}
	if err != nil {
		log.Fatal(err)
	}

	// parse config
	yamlDoc, err := ioutil.ReadFile(dir + "config.yml")
	if err != nil {
		log.Fatal(err)
	}
	jsonDoc, err := yaml.YAMLToJSON(yamlDoc)
	if err != nil {
		fmt.Printf("Error converting YAML to JSON: %s\n", err.Error())
		return
	}
	var someStruct map[string]interface{}
	err = json.Unmarshal(jsonDoc, &someStruct)
	if err != nil {
		fmt.Printf("Error unmarshaling JSON: %s\n", err.Error())
		return
	}
	var finderConfig map[string]string
	finderConfig = make(map[string]string)
	for elem := range someStruct {
		if reflect.TypeOf(elem).Name() == "string" {
			elemsSlice := someStruct[elem].(map[string]interface{})
			for elem2 := range elemsSlice {
				if reflect.TypeOf(elem2).Name() == "string" {
					elems2Slice := elemsSlice[elem2].([]interface{})
					for i, cat := range elems2Slice {
						if i < len(elems2Slice)-1 {
							finderConfig[elem2] += fmt.Sprintf(`%s\w{0,2}|`, cat)
						} else {
							finderConfig[elem2] += fmt.Sprintf(`%s\w{0,2}`, cat)
						}
					}
				}
			}
		}
	}

	// e-mail folder
	emaildir := dir + "emails"
	emailpath := filepath.FromSlash(dir + "emails")
	files, err := ioutil.ReadDir(emailpath)
	if err != nil {
		log.Fatal(err)
	}

	// analyse
	persons := make(map[string]person)
	for _, file := range files {
		if file.Name()[len(file.Name())-4:len(file.Name())] == ".eml" {
			analyseFile(emaildir+"/"+file.Name(), persons, finderConfig)
		}
	}

	// write CSV
	rows := [][]string{
		{"E-Mail", "Category", "Double-Category (Y|N)}"},
	}

	tn := time.Now()
	fn := fmt.Sprintf("%d-%02d-%02d_%02d_%02d_%02d-results.csv", tn.Year(), tn.Month(), tn.Day(), tn.Hour(), tn.Minute(), tn.Second())
	csvpath := filepath.FromSlash(dir + fn)
	csvfile, err := os.Create(csvpath)
	if err != nil {
		log.Fatal(err)
	}

	csvwriter := csv.NewWriter(csvfile)
	for _, v := range persons {
		for _, e := range v.categories {
			if v.double == true {
				rows = append(rows, []string{v.email, e, "Y"})
			} else {
				rows = append(rows, []string{v.email, e, "N"})
			}
		}
	}
	for _, row := range rows {
		_ = csvwriter.Write(row)
	}

	csvwriter.Flush()
	csvfile.Close()

	// end with some information
	fmt.Printf("> Analysed %d E-Mails\n", len(files))
	fmt.Printf("> Wrote output to %s\n\n", csvpath)
}

license: MIT

license_type: permissive

branch_name: refs/heads/master

extension: go


text:
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: google/ads/googleads/v3/enums/interaction_event_type.proto

package enums

import (
	fmt "fmt"
	math "math"

	proto "github.com/catper/protobuf/proto"
	_ "google.golang.org/genproto/googleapis/api/annotations"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package

// Enum describing possible types of payable and free interactions.
type InteractionEventTypeEnum_InteractionEventType int32

const (
	// Not specified.
	InteractionEventTypeEnum_UNSPECIFIED InteractionEventTypeEnum_InteractionEventType = 0
	// Used for return value only. Represents value unknown in this version.
	InteractionEventTypeEnum_UNKNOWN InteractionEventTypeEnum_InteractionEventType = 1
	// Click to site. In most cases, this interaction navigates to an external
	// location, usually the advertiser's landing page. This is also the default
	// InteractionEventType for click events.
	InteractionEventTypeEnum_CLICK InteractionEventTypeEnum_InteractionEventType = 2
	// The user's expressed intent to engage with the ad in-place.
	InteractionEventTypeEnum_ENGAGEMENT InteractionEventTypeEnum_InteractionEventType = 3
	// User viewed a video ad.
	InteractionEventTypeEnum_VIDEO_VIEW InteractionEventTypeEnum_InteractionEventType = 4
	// The default InteractionEventType for ad conversion events.
	// This is used when an ad conversion row does NOT indicate
	// that the free interactions (i.e., the ad conversions)
	// should be 'promoted' and reported as part of the core metrics.
	// These are simply other (ad) conversions.
	InteractionEventTypeEnum_NONE InteractionEventTypeEnum_InteractionEventType = 5
)

var InteractionEventTypeEnum_InteractionEventType_name = map[int32]string{
	0: "UNSPECIFIED",
	1: "UNKNOWN",
	2: "CLICK",
	3: "ENGAGEMENT",
	4: "VIDEO_VIEW",
	5: "NONE",
}

var InteractionEventTypeEnum_InteractionEventType_value = map[string]int32{
	"UNSPECIFIED": 0,
	"UNKNOWN":     1,
	"CLICK":       2,
	"ENGAGEMENT":  3,
	"VIDEO_VIEW":  4,
	"NONE":        5,
}

func (x InteractionEventTypeEnum_InteractionEventType) String() string {
	return proto.EnumName(InteractionEventTypeEnum_InteractionEventType_name, int32(x))
}

func (InteractionEventTypeEnum_InteractionEventType) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_d3dbb1c76f569f9a, []int{0, 0}
}

// Container for enum describing types of payable and free interactions.
type InteractionEventTypeEnum struct {
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *InteractionEventTypeEnum) Reset()         { *m = InteractionEventTypeEnum{} }
func (m *InteractionEventTypeEnum) String() string { return proto.CompactTextString(m) }
func (*InteractionEventTypeEnum) ProtoMessage()    {}
func (*InteractionEventTypeEnum) Descriptor() ([]byte, []int) {
	return fileDescriptor_d3dbb1c76f569f9a, []int{0}
}

func (m *InteractionEventTypeEnum) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_InteractionEventTypeEnum.Unmarshal(m, b)
}
func (m *InteractionEventTypeEnum) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_InteractionEventTypeEnum.Marshal(b, m, deterministic)
}
func (m *InteractionEventTypeEnum) XXX_Merge(src proto.Message) {
	xxx_messageInfo_InteractionEventTypeEnum.Merge(m, src)
}
func (m *InteractionEventTypeEnum) XXX_Size() int {
	return xxx_messageInfo_InteractionEventTypeEnum.Size(m)
}
func (m *InteractionEventTypeEnum) XXX_DiscardUnknown() {
	xxx_messageInfo_InteractionEventTypeEnum.DiscardUnknown(m)
}

var xxx_messageInfo_InteractionEventTypeEnum proto.InternalMessageInfo

func init() {
	proto.RegisterEnum("google.ads.googleads.v3.enums.InteractionEventTypeEnum_InteractionEventType", InteractionEventTypeEnum_InteractionEventType_name, InteractionEventTypeEnum_InteractionEventType_value)
	proto.RegisterType((*InteractionEventTypeEnum)(nil), "google.ads.googleads.v3.enums.InteractionEventTypeEnum")
}

func init() {
	proto.RegisterFile("google/ads/googleads/v3/enums/interaction_event_type.proto", fileDescriptor_d3dbb1c76f569f9a)
}

var fileDescriptor_d3dbb1c76f569f9a = []byte{
	// 334 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x50, 0xdd, 0x4e, 0xc2, 0x30,
	0x18, 0x75, 0x03, 0xfc, 0x29, 0x89, 0x2e, 0x8b, 0x17, 0x6a, 0xe4, 0x02, 0x1e, 0xa0, 0xbb, 0xd8,
	0x5d, 0xbd, 0x1a, 0x50, 0x97, 0x05, 0x2d, 0x24, 0xc2, 0x48, 0xcc, 0x12, 0x32, 0x59, 0xd3, 0x2c,
	0x81, 0x76, 0xa1, 0x85, 0x84, 0x07, 0xf0, 0x45, 0xbc, 0xf4, 0x51, 0x7c, 0x14, 0x2f, 0x7c, 0x06,
	0xd3, 0x56, 0xf0, 0x06, 0xbd, 0x69, 0x4e, 0xbf, 0xf3, 0x9d, 0x93, 0xef, 0x1c, 0x80, 0x98, 0x10,
	0x6c, 0x41, 0x83, 0xbc, 0x90, 0x81, 0x85, 0x1a, 0x6d, 0xc2, 0x80, 0xf2, 0xf5, 0x52, 0x06, 0x25,
	0x57, 0x74, 0x95, 0xcf, 0x55, 0x29, 0xf8, 0x8c, 0x6e, 0x28, 0x57, 0x33, 0xb5, 0xad, 0x28, 0xac,
	0x56, 0x42, 0x09, 0xbf, 0x65, 0x05, 0x30, 0x2f, 0x24, 0xdc, 0x6b, 0xe1, 0x26, 0x84, 0x46, 0x7b,
	0x73, 0xbb, 0xb3, 0xae, 0xca, 0x20, 0xe7, 0x5c, 0xa8, 0x5c, 0xdb, 0x48, 0x2b, 0xee, 0xbc, 0x3a,
	0xe0, 0x2a, 0xf9, 0x75, 0xc7, 0xda, 0x7c, 0xbc, 0xad, 0x28, 0xe6, 0xeb, 0x65, 0xa7, 0x04, 0x97,
	0x87, 0x38, 0xff, 0x02, 0x34, 0x27, 0xe4, 0x69, 0x84, 0x7b, 0xc9, 0x7d, 0x82, 0xfb, 0xde, 0x91,
	0xdf, 0x04, 0x27, 0x13, 0x32, 0x20, 0xc3, 0x29, 0xf1, 0x1c, 0xff, 0x0c, 0x34, 0x7a, 0x0f, 0x49,
	0x6f, 0xe0, 0xb9, 0xfe, 0x39, 0x00, 0x98, 0xc4, 0x51, 0x8c, 0x1f, 0x31, 0x19, 0x7b, 0x35, 0xfd,
	0x4f, 0x93, 0x3e, 0x1e, 0xce, 0xd2, 0x04, 0x4f, 0xbd, 0xba, 0x7f, 0x0a, 0xea, 0x64, 0x48, 0xb0,
	0xd7, 0xe8, 0x7e, 0x39, 0xa0, 0x3d, 0x17, 0x4b, 0xf8, 0x6f, 0x96, 0xee, 0xf5, 0xa1, 0x73, 0x46,
	0x3a, 0xc8, 0xc8, 0x79, 0xee, 0xfe, 0x68, 0x99, 0x58, 0xe4, 0x9c, 0x41, 0xb1, 0x62, 0x01, 0xa3,
	0xdc, 0xc4, 0xdc, 0x75, 0x5a, 0x95, 0xf2, 0x8f, 0x8a, 0xef, 0xcc, 0xfb, 0xe6, 0xd6, 0xe2, 0x28,
	0x7a, 0x77, 0x5b, 0xb1, 0xb5, 0x8a, 0x0a, 0x09, 0x2d, 0xd4, 0x28, 0x0d, 0xa1, 0xae, 0x45, 0x7e,
	0xec, 0xf8, 0x2c, 0x2a, 0x64, 0xb6, 0xe7, 0xb3, 0x34, 0xcc, 0x0c, 0xff, 0xe9, 0xb6, 0xed, 0x10,
	0xa1, 0xa8, 0x90, 0x08, 0xed, 0x37, 0x10, 0x4a, 0x43, 0x84, 0xcc, 0xce, 0xcb, 0xb1, 0x39, 0x2c,
	0xfc, 0x0e, 0x00, 0x00, 0xff, 0xff, 0x28, 0x56, 0xeb, 0x66, 0xfa, 0x01, 0x00, 0x00,
}

repository: catper/go-genproto

repo_name: catper/go-genproto


text:
/*
Copyright 2021 The Kubernetes Authors.

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 loadbalancers

import (
	"fmt"
	"strings"
	"sync"
	"testing"

	"github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud"
	"github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta"
	v1 "k8s.io/api/core/v1"
	"k8s.io/client-go/tools/record"
	servicehelper "k8s.io/cloud-provider/service/helpers"
	"k8s.io/ingress-gce/pkg/annotations"
	"k8s.io/ingress-gce/pkg/composite"
	"k8s.io/ingress-gce/pkg/test"
	"k8s.io/ingress-gce/pkg/utils"
	namer_util "k8s.io/ingress-gce/pkg/utils/namer"
	"k8s.io/legacy-cloud-providers/gce"
)

func TestEnsureL4NetLoadBalancer(t *testing.T) {
	t.Parallel()
	nodeNames := []string{"test-node-1"}
	vals := gce.DefaultTestClusterValues()
	fakeGCE := getFakeGCECloud(vals)

	svc := test.NewL4NetLBService(8080)
	namer := namer_util.NewL4Namer(kubeSystemUID, namer_util.NewNamer(vals.ClusterName, "cluster-fw"))

	l4netlb := NewL4NetLB(svc, fakeGCE, meta.Regional, namer, record.NewFakeRecorder(100), &sync.Mutex{})

	if _, err := test.CreateAndInsertNodes(l4netlb.cloud, nodeNames, vals.ZoneName); err != nil {
		t.Errorf("Unexpected error when adding nodes %v", err)
	}
	result := l4netlb.EnsureFrontend(nodeNames, svc)
	if result.Error != nil {
		t.Errorf("Failed to ensure loadBalancer, err %v", result.Error)
	}
	if len(result.Status.Ingress) == 0 {
		t.Errorf("Got empty loadBalancer status using handler %v", l4netlb)
	}
	if err := checkAnnotations(result, l4netlb); err != nil {
		t.Errorf("Annotations error: %v", err)
	}
	assertNetLbResources(t, svc, l4netlb, nodeNames)
}

func checkAnnotations(result *L4LBSyncResult, l4netlb *L4NetLB) error {
	expBackendName := l4netlb.ServicePort.BackendName()
	if result.Annotations[annotations.BackendServiceKey] != expBackendName {
		return fmt.Errorf("BackendServiceKey mismatch %v != %v", expBackendName, result.Annotations[annotations.BackendServiceKey])
	}
	expTcpFR := l4netlb.GetFRName()
	if result.Annotations[annotations.TCPForwardingRuleKey] != expTcpFR {
		return fmt.Errorf("TCPForwardingRuleKey mismatch %v != %v", expTcpFR, result.Annotations[annotations.TCPForwardingRuleKey])
	}
	expFwRule := expBackendName
	if result.Annotations[annotations.FirewallRuleKey] != expFwRule {
		return fmt.Errorf("FirewallRuleKey mismatch %v != %v", expFwRule, result.Annotations[annotations.FirewallRuleKey])
	}
	_, expHcFwName := l4netlb.namer.L4HealthCheck(l4netlb.Service.Namespace, l4netlb.Service.Name, true)
	if result.Annotations[annotations.FirewallRuleForHealthcheckKey] != expHcFwName {
		return fmt.Errorf("FirewallRuleForHealthcheckKey mismatch %v != %v", expHcFwName, result.Annotations[annotations.FirewallRuleForHealthcheckKey])
	}
	return nil
}

func TestDeleteL4NetLoadBalancer(t *testing.T) {
	t.Parallel()
	nodeNames := []string{"test-node-1"}
	vals := gce.DefaultTestClusterValues()
	fakeGCE := getFakeGCECloud(vals)

	svc := test.NewL4NetLBService(8080)
	namer := namer_util.NewL4Namer(kubeSystemUID, namer_util.NewNamer(vals.ClusterName, "cluster-fw"))

	l4NetLB := NewL4NetLB(svc, fakeGCE, meta.Regional, namer, record.NewFakeRecorder(100), &sync.Mutex{})

	if _, err := test.CreateAndInsertNodes(l4NetLB.cloud, nodeNames, vals.ZoneName); err != nil {
		t.Errorf("Unexpected error when adding nodes %v", err)
	}
	result := l4NetLB.EnsureFrontend(nodeNames, svc)
	if result.Error != nil {
		t.Errorf("Failed to ensure loadBalancer, err %v", result.Error)
	}
	if len(result.Status.Ingress) == 0 {
		t.Errorf("Got empty loadBalancer status using handler %v", l4NetLB)
	}
	assertNetLbResources(t, svc, l4NetLB, nodeNames)

	if err := l4NetLB.EnsureLoadBalancerDeleted(svc); err.Error != nil {
		t.Errorf("UnexpectedError %v", err.Error)
	}
	ensureNetLBResourceDeleted(t, svc, l4NetLB)
}

func TestDeleteL4NetLoadBalancerWithSharedHC(t *testing.T) {
	t.Parallel()
	vals := gce.DefaultTestClusterValues()
	fakeGCE := getFakeGCECloud(vals)
	(fakeGCE.Compute().(*cloud.MockGCE)).MockRegionHealthChecks.DeleteHook = test.DeleteRegionalHealthCheckResourceInUseErrorHook

	_, _ = ensureLoadBalancer(8080, vals, fakeGCE, t)
	svc, l4NetLB := ensureLoadBalancer(8081, vals, fakeGCE, t)

	if err := l4NetLB.EnsureLoadBalancerDeleted(svc); err.Error != nil {
		t.Errorf("UnexpectedError %v", err.Error)
	}
	// Health check is in used by second service
	// we expect that firewall rule will not be deleted
	_, hcFwName := l4NetLB.namer.L4HealthCheck(svc.Namespace, svc.Name, true)
	firewall, err := l4NetLB.cloud.GetFirewall(hcFwName)
	if err != nil || firewall == nil {
		t.Fatalf("Firewall rule should not be deleted err: %v", err)
	}
}

func ensureLoadBalancer(port int, vals gce.TestClusterValues, fakeGCE *gce.Cloud, t *testing.T) (*v1.Service, *L4NetLB) {
	svc := test.NewL4NetLBService(port)
	namer := namer_util.NewL4Namer(kubeSystemUID, namer_util.NewNamer(vals.ClusterName, "cluster-fw"))
	emptyNodes := []string{}
	l4NetLB := NewL4NetLB(svc, fakeGCE, meta.Regional, namer, record.NewFakeRecorder(100), &sync.Mutex{})
	result := l4NetLB.EnsureFrontend(emptyNodes, svc)
	if result.Error != nil {
		t.Errorf("Failed to ensure loadBalancer, err %v", result.Error)
	}
	if len(result.Status.Ingress) == 0 {
		t.Errorf("Got empty loadBalancer status using handler %v", l4NetLB)
	}
	assertNetLbResources(t, svc, l4NetLB, emptyNodes)
	return svc, l4NetLB
}

func ensureNetLBResourceDeleted(t *testing.T, apiService *v1.Service, l4NetLb *L4NetLB) {
	t.Helper()

	resourceName := l4NetLb.ServicePort.BackendName()
	sharedHC := !servicehelper.RequestsOnlyLocalTraffic(apiService)
	hcName, hcFwName := l4NetLb.namer.L4HealthCheck(apiService.Namespace, apiService.Name, sharedHC)

	for _, fwName := range []string{resourceName, hcFwName} {
		_, err := l4NetLb.cloud.GetFirewall(fwName)
		if err == nil || !utils.IsNotFoundError(err) {
			t.Fatalf("Firewall rule %q should be deleted", fwName)
		}
	}

	_, err := composite.GetHealthCheck(l4NetLb.cloud, meta.RegionalKey(hcName, l4NetLb.cloud.Region()), meta.VersionGA)
	if err == nil || !strings.Contains(err.Error(), "not found") {
		t.Errorf("Healthcheck %s should be deleted", hcName)
	}

	key := meta.RegionalKey(resourceName, l4NetLb.cloud.Region())
	_, err = composite.GetBackendService(l4NetLb.cloud, key, meta.VersionGA)
	if err == nil || !strings.Contains(err.Error(), "not found") {
		t.Errorf("Failed to fetch backend service %s - err %v", resourceName, err)
	}

	frName := l4NetLb.GetFRName()
	_, err = composite.GetForwardingRule(l4NetLb.cloud, meta.RegionalKey(frName, l4NetLb.cloud.Region()), meta.VersionGA)
	if err == nil || !strings.Contains(err.Error(), "not found") {
		t.Errorf("Forwarding rule %s should be deleted", frName)
	}

	addr, err := l4NetLb.cloud.GetRegionAddress(frName, l4NetLb.cloud.Region())
	if err == nil || addr != nil {
		t.Errorf("Address %v should be deleted", addr)
	}
}

func assertNetLbResources(t *testing.T, apiService *v1.Service, l4NetLb *L4NetLB, nodeNames []string) {
	t.Helper()
	// Check that Firewalls are created for the LoadBalancer and the HealthCheck
	resourceName := l4NetLb.ServicePort.BackendName()

	_, _, _, proto := utils.GetPortsAndProtocol(apiService.Spec.Ports)

	hcName, hcFwName := l4NetLb.namer.L4HealthCheck(apiService.Namespace, apiService.Name, true)

	fwNamesAndDesc := []string{resourceName, hcFwName}

	if hcFwName == resourceName {
		t.Errorf("Got the same name %q for LB firewall rule and Healthcheck firewall rule", hcFwName)
	}
	for _, fwName := range fwNamesAndDesc {
		firewall, err := l4NetLb.cloud.GetFirewall(fwName)
		if err != nil {
			t.Fatalf("Failed to fetch firewall rule %q - err %v", fwName, err)
		}
		if !utils.EqualStringSets(nodeNames, firewall.TargetTags) {
			t.Fatalf("Expected firewall rule target tags '%v', Got '%v'", nodeNames, firewall.TargetTags)
		}
		if len(firewall.SourceRanges) == 0 {
			t.Fatalf("Unexpected empty source range for firewall rule %v", firewall)
		}
	}

	// Check that HealthCheck is created
	healthcheck, err := composite.GetHealthCheck(l4NetLb.cloud, meta.RegionalKey(hcName, l4NetLb.cloud.Region()), meta.VersionGA)
	if err != nil {
		t.Errorf("Failed to fetch healthcheck %s - err %v", hcName, err)
	}
	if healthcheck.Name != hcName {
		t.Errorf("Unexpected name for healthcheck '%s' - expected '%s'", healthcheck.Name, hcName)
	}

	// Check that BackendService exists
	backendServiceName := resourceName
	key := meta.RegionalKey(backendServiceName, l4NetLb.cloud.Region())
	backendServiceLink := cloud.SelfLink(meta.VersionGA, l4NetLb.cloud.ProjectID(), "backendServices", key)
	bs, err := composite.GetBackendService(l4NetLb.cloud, key, meta.VersionGA)
	if err != nil {
		t.Errorf("Failed to fetch backend service %s - err %v", backendServiceName, err)
	}
	if bs.Protocol != string(proto) {
		t.Errorf("Unexpected protocol '%s' for backend service %v", bs.Protocol, bs)
	}
	if bs.SelfLink != backendServiceLink {
		t.Errorf("Unexpected self link in backend service - Expected %s, Got %s", bs.SelfLink, backendServiceLink)
	}
	if bs.LoadBalancingScheme != string(cloud.SchemeExternal) {
		t.Errorf("Unexpected load balancing scheme - Expected EXTERNAL, Got %s", bs.LoadBalancingScheme)
	}

	if !utils.EqualStringSets(bs.HealthChecks, []string{healthcheck.SelfLink}) {
		t.Errorf("Unexpected healthcheck reference '%v' in backend service, expected '%s'", bs.HealthChecks,
			healthcheck.SelfLink)
	}
	// Check that ForwardingRule is created
	frName := l4NetLb.GetFRName()
	fwdRule, err := composite.GetForwardingRule(l4NetLb.cloud, meta.RegionalKey(frName, l4NetLb.cloud.Region()), meta.VersionGA)
	if err != nil {
		t.Errorf("Failed to fetch forwarding rule %s - err %v", frName, err)
	}
	if fwdRule.Name != frName {
		t.Errorf("Unexpected name for forwarding rule '%s' - expected '%s'", fwdRule.Name, frName)
	}
	if fwdRule.IPProtocol != string(proto) {
		t.Errorf("Unexpected protocol '%s' for forwarding rule %v", fwdRule.IPProtocol, fwdRule)
	}
	if fwdRule.BackendService != backendServiceLink {
		t.Errorf("Unexpected backend service link '%s' for forwarding rule, expected '%s'", fwdRule.BackendService, backendServiceLink)
	}

	addr, err := l4NetLb.cloud.GetRegionAddress(frName, l4NetLb.cloud.Region())
	if err == nil || addr != nil {
		t.Errorf("Expected error when looking up ephemeral address, got %v", addr)
	}
}

repository: bowei/ingress-gce

repo_name: bowei/ingress-gce

gha_language: Go


text:
@article{Orom2010a,
 abstract = {While the long noncoding RNAs (ncRNAs) constitute a large portion of the mammalian transcriptome, their biological functions has remained elusive. A few long ncRNAs that have been studied in any detail silence gene expression in processes such as X-inactivation and imprinting. We used a GENCODE annotation of the human genome to characterize over a thousand long ncRNAs that are expressed in multiple cell lines. Unexpectedly, we found an enhancer-like function for a set of these long ncRNAs in human cell lines. Depletion of a number of ncRNAs led to decreased expression of their neighboring protein-coding genes, including the master regulator of hematopoiesis, SCL (also called TAL1), Snai1 and Snai2. Using heterologous transcription assays we demonstrated a requirement for the ncRNAs in activation of gene expression. These results reveal an unanticipated role for a class of long ncRNAs in activation of critical regulators of development and differentiation.},
 author = {Orom, Ulf Andersson and Derrien, Thomas and Beringer, Malte and Gumireddy, Kiranmai and Gardini, Alessandro and Bussotti, Giovanni and Lai, Fan and Zytnicki, Matthias and Notredame, Cedric and Huang, Qihong and Guigo, Roderic and Shiekhattar, Ramin},
 doi = {10.1016/j.cell.2010.09.001},
 issn = {1097-4172 (Electronic)},
 journal = {Cell},
 keywords = {Cell Line,Cell Line, Tumor,Cells, Cultured,Enhancer Elements, Genetic,Genome, Human,Humans,RNA, Messenger,RNA, Untranslated,Snail Family Transcription Factors,Transcription Factors,Transcriptional Activation,genetics,metabolism},
 language = {eng},
 month = {oct},
 number = {1},
 pages = {46--58},
 pmid = {20887892},
 title = {Long noncoding RNAs with enhancer-like function in human cells.},
 volume = {143},
 year = {2010}
}

extension: bib