From 7093dfd0ebf452a51919a60ee0d91bbcf21bd810 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 9 Jan 2021 15:56:55 +0100 Subject: [PATCH] WIP: bug fixes, more tests for complex DRC --- src/db/db/dbHierProcessor.cc | 9 +- src/db/db/dbRegionLocalOperations.cc | 123 +++++++++++------- .../built-in-macros/_drc_cop_integration.rb | 3 +- src/drc/unit_tests/drcGenericTests.cc | 10 ++ testdata/drc/drcGenericTests_3.drc | 36 +++++ testdata/drc/drcGenericTests_3.gds | Bin 0 -> 1306 bytes testdata/drc/drcGenericTests_au3.gds | Bin 0 -> 13866 bytes testdata/drc/drcGenericTests_au3d.gds | Bin 0 -> 13530 bytes testdata/drc/drcSimpleTests_25.drc | 30 +++++ testdata/drc/drcSimpleTests_25.gds | Bin 0 -> 2526 bytes testdata/drc/drcSimpleTests_au25.gds | Bin 0 -> 8490 bytes testdata/drc/drcSimpleTests_au25d.gds | Bin 0 -> 8094 bytes 12 files changed, 161 insertions(+), 50 deletions(-) create mode 100644 testdata/drc/drcGenericTests_3.drc create mode 100644 testdata/drc/drcGenericTests_3.gds create mode 100644 testdata/drc/drcGenericTests_au3.gds create mode 100644 testdata/drc/drcGenericTests_au3d.gds create mode 100644 testdata/drc/drcSimpleTests_25.drc create mode 100644 testdata/drc/drcSimpleTests_25.gds create mode 100644 testdata/drc/drcSimpleTests_au25.gds create mode 100644 testdata/drc/drcSimpleTests_au25d.gds diff --git a/src/db/db/dbHierProcessor.cc b/src/db/db/dbHierProcessor.cc index 14f49f696..72f5ba68d 100644 --- a/src/db/db/dbHierProcessor.cc +++ b/src/db/db/dbHierProcessor.cc @@ -1553,7 +1553,8 @@ void local_processor::compute_contexts (local_processor_contexts::const_iterator il = contexts.intruder_layers ().begin (); il != contexts.intruder_layers ().end (); ++il) { - db::box_convert inst_bcii (*mp_intruder_layout, contexts.actual_intruder_layer (*il)); + unsigned int ail = contexts.actual_intruder_layer (*il); + db::box_convert inst_bcii (*mp_intruder_layout, ail); for (std::unordered_set::const_iterator j = i->second.first.begin (); j != i->second.first.end (); ++j) { for (db::CellInstArray::iterator k = (*j)->begin_touching (safe_box_enlarged (nbox, -1, -1), inst_bcii); ! k.at_end (); ++k) { @@ -1561,7 +1562,7 @@ void local_processor::compute_contexts (local_processor_contextsfirst != *j || tn != tk) { // optimize the intruder instance so it will be as low as possible - std::pair ei = effective_instance (contexts.subject_layer (), i->first->object ().cell_index (), contexts.actual_intruder_layer (*il), (*j)->object ().cell_index (), tni * tk, dist); + std::pair ei = effective_instance (contexts.subject_layer (), i->first->object ().cell_index (), ail, (*j)->object ().cell_index (), tni * tk, dist); if (ei.first) { intruders_below.first.insert (ei.second); } @@ -1902,7 +1903,7 @@ local_processor::compute_local_cell (const db::local_processor_conte db::box_convert inst_bci (*mp_intruder_layout, ail); - typename std::map >::const_iterator ipl = intruders.second.find (ail); + typename std::map >::const_iterator ipl = intruders.second.find (*il); static std::set empty_intruders; if (! subject_shapes->empty () && (intruder_shapes || ipl != intruders.second.end ())) { @@ -1932,7 +1933,7 @@ local_processor::compute_local_cell (const db::local_processor_conte unsigned int inst_id = 0; - if (subject_cell == intruder_cell && contexts.subject_layer () == ail) { + if (subject_cell == intruder_cell && contexts.subject_layer () == ail && !foreign) { // Same cell, same layer -> no shape to child instance interactions because this will be taken care of // by the instances themselves (and their intruders). This also means, we prefer to deal with diff --git a/src/db/db/dbRegionLocalOperations.cc b/src/db/db/dbRegionLocalOperations.cc index 0746d55d9..7628ae04e 100644 --- a/src/db/db/dbRegionLocalOperations.cc +++ b/src/db/db/dbRegionLocalOperations.cc @@ -145,6 +145,56 @@ void insert_into_hash (std::unordered_set &hash, const T &shape) } +template +static +uint32_t compute_error_pattern (const TS &subject, std::unordered_set &result, std::map &edges_with_errors) +{ + uint32_t p = 1; + for (typename TS::polygon_edge_iterator e = subject.begin_edge (); ! e.at_end (); ++e) { + edges_with_errors [*e] = p; + p <<= 1; + } + + uint32_t error_pattern = 0; + for (std::unordered_set::const_iterator ep = result.begin (); ep != result.end (); ++ep) { + std::map::iterator i = edges_with_errors.find (ep->first ()); + if (i != edges_with_errors.end ()) { + if ((error_pattern & i->second) == 0) { + error_pattern |= i->second; + } + } + } + + return error_pattern; +} + +static bool rect_filter_can_be_waived (uint32_t error_pattern, uint32_t rect_filter) +{ + if (! error_pattern) { + return false; + } + + bool can_be_waived = false; + + // decode pattern: consider each group of 4 bits and match them against the error pattern in their four rotation variants + uint32_t p32 = (uint32_t) rect_filter; + while (p32 != 0 && ! can_be_waived) { + + uint32_t p4 = p32 & 0xf; + p32 >>= 4; + + if (p4 > 0) { + for (unsigned int r = 0; r < 4 && ! can_be_waived; ++r) { + can_be_waived = (error_pattern == p4); + p4 = ((p4 << 1) & 0xf) | ((p4 & 0x8) >> 3); + } + } + + } + + return can_be_waived; +} + template void check_local_operation::do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const @@ -413,52 +463,16 @@ check_local_operation::do_compute_local (db::Layout *layout, const shape continue; } - unsigned int p = 1; - std::map edges_with_errors; - for (typename TS::polygon_edge_iterator e = subject.begin_edge (); ! e.at_end (); ++e) { - edges_with_errors [*e] = p; - p <<= 1; - } + std::map edges_with_errors; + unsigned int error_pattern = compute_error_pattern (subject, result, edges_with_errors); - unsigned int error_pattern = 0; - for (std::unordered_set::const_iterator ep = result.begin (); ep != result.end (); ++ep) { - std::map::iterator i = edges_with_errors.find (ep->first ()); - if (i != edges_with_errors.end ()) { - if ((error_pattern & i->second) == 0) { - error_pattern |= i->second; + if (rect_filter_can_be_waived (error_pattern, (uint32_t) m_options.rect_filter)) { + + for (std::unordered_set::const_iterator ep = result.begin (); ep != result.end (); ++ep) { + if (edges_with_errors.find (ep->first ()) != edges_with_errors.end ()) { + waived.insert (*ep); } } - } - - if (error_pattern != 0) { - - bool can_be_waived = false; - - // decode pattern: consider each group of 4 bits and match them against the error pattern in their four rotation variants - uint32_t p32 = (uint32_t) m_options.rect_filter; - while (p32 != 0 && ! can_be_waived) { - - uint32_t p4 = p32 & 0xf; - p32 >>= 4; - - if (p4 > 0) { - for (unsigned int r = 0; r < 4 && ! can_be_waived; ++r) { - can_be_waived = (error_pattern == p4); - p4 = ((p4 << 1) & 0xf) | ((p4 & 0x8) >> 3); - } - } - - } - - if (can_be_waived) { - - for (std::unordered_set::const_iterator ep = result.begin (); ep != result.end (); ++ep) { - if (edges_with_errors.find (ep->first ()) != edges_with_errors.end ()) { - waived.insert (*ep); - } - } - - } } @@ -470,9 +484,28 @@ check_local_operation::do_compute_local (db::Layout *layout, const shape } } - } + if (! m_has_other) { - results.front ().insert (result.begin (), result.end ()); + // this is the case of single-layer interaction. We need to separate the results + // from edge pairs into single edges (basically returning the first edge only) + // Reasoning: we cannot say what's going to happen on the other side of the + // error - it may not be waived and we cannot waive half of an edge pair. + + for (std::unordered_set::const_iterator i = result.begin (); i != result.end (); ++i) { + results.front ().insert (db::EdgePair (i->first (), i->first ().swapped_points ())); + } + + } else { + + results.front ().insert (result.begin (), result.end ()); + + } + + } else { + + results.front ().insert (result.begin (), result.end ()); + + } } template diff --git a/src/drc/drc/built-in-macros/_drc_cop_integration.rb b/src/drc/drc/built-in-macros/_drc_cop_integration.rb index 58d6a25be..367ea1939 100644 --- a/src/drc/drc/built-in-macros/_drc_cop_integration.rb +++ b/src/drc/drc/built-in-macros/_drc_cop_integration.rb @@ -77,7 +77,8 @@ module DRC @engine._context("drc") do requires_region op.is_a?(DRCOpNode) || raise("A DRC expression is required for the argument (got #{op.inspect})") - DRCLayer::new(@engine, self.data.complex_op(op.create_node({}))) + # @@@ proper output type!!! + DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :complex_op, op.create_node({}))) end end diff --git a/src/drc/unit_tests/drcGenericTests.cc b/src/drc/unit_tests/drcGenericTests.cc index 2f5e766a2..bf489b85e 100644 --- a/src/drc/unit_tests/drcGenericTests.cc +++ b/src/drc/unit_tests/drcGenericTests.cc @@ -88,3 +88,13 @@ TEST(2d) { run_test (_this, "2", true); } + +TEST(3) +{ + run_test (_this, "3", false); +} + +TEST(3d) +{ + run_test (_this, "3", true); +} diff --git a/testdata/drc/drcGenericTests_3.drc b/testdata/drc/drcGenericTests_3.drc new file mode 100644 index 000000000..c4fb24014 --- /dev/null +++ b/testdata/drc/drcGenericTests_3.drc @@ -0,0 +1,36 @@ + +source $drc_test_source +target $drc_test_target + +if $drc_test_deep + deep + threads(0) # easier to debug +end + +l1 = input(1, 0) +l2 = input(2, 0) +l3 = input(3, 0) + +l1.output(1, 0) +l2.output(2, 0) +l3.output(3, 0) + +# space with rectangle side selection option +l1.drc(space(projection) < 1.um).polygons.output(100, 0) +l1.drc(space(projection, one_side_allowed) < 1.um).output(101, 0) +l1.drc(space(projection, two_sides_allowed) < 1.um).output(102, 0) +l1.drc(space(projection, three_sides_allowed) < 1.um).output(103, 0) + +# space with rectangle side selection option +l1.drc(iso(projection) < 1.um).polygons.output(110, 0) +l1.drc(iso(projection, one_side_allowed) < 1.um).output(111, 0) +l1.drc(iso(projection, two_sides_allowed) < 1.um).output(112, 0) +l1.drc(iso(projection, three_sides_allowed) < 1.um).output(113, 0) + +# separation with rectangle side selection option +l1.drc(sep(l2, projection) < 1.um).polygons.output(120, 0) +l1.drc(sep(l2, projection, one_side_allowed) < 1.um).polygons.output(121, 0) +l1.drc(sep(l2, projection, two_sides_allowed) < 1.um).polygons.output(122, 0) +l1.drc(sep(l2, projection, three_sides_allowed) < 1.um).polygons.output(123, 0) + + diff --git a/testdata/drc/drcGenericTests_3.gds b/testdata/drc/drcGenericTests_3.gds new file mode 100644 index 0000000000000000000000000000000000000000..0b48167b1c1729471f6d589d18cf7649146d0dd7 GIT binary patch literal 1306 zcmah}Jxjw-6un8)*V;Bxi-;d}5EVZtDk6v?LTiT>3p#Wt;^+@?75o8$iTBk(0VzP4MRbkGk$-lh0M4ta;rKZ2^$|F&TRR#2IbXq?= zd3nRrj=ZheMfL?^D$5@Mg7NuS{rVm2fzWSX1PI3GWA!`dUgZRwI3cPY2WUF-;?h~V z&)0_hQ!Vyc$g{to#0|#!mtMJkApFw(bEYy=3#=LhJu{+z>eT7T!@ zAE3kyhV`Ls;n`tMxZ#hU1ts1yzla`N3Jq|+$nQ>2;yv>V>3J*NHY0qkF8c!|9`Db+ kVpGsNz90E(03~h?G5y0ATgHeSR+n=DB`#ZNcG+?02ZGzfi~s-t literal 0 HcmV?d00001 diff --git a/testdata/drc/drcGenericTests_au3.gds b/testdata/drc/drcGenericTests_au3.gds new file mode 100644 index 0000000000000000000000000000000000000000..e27936c10333ee6c4fabf7e6e4ad2958cb423383 GIT binary patch literal 13866 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 literal 0 HcmV?d00001 diff --git a/testdata/drc/drcGenericTests_au3d.gds b/testdata/drc/drcGenericTests_au3d.gds new file mode 100644 index 0000000000000000000000000000000000000000..170651e206b415688961b9301f4eae9e4202d569 GIT binary patch literal 13530 zcmbuF&5u+?6vb;AXhwz+Bqpc~i^*t4$f%P+G!kM0k_drB7bKu@2k1^<=f}paQP*l* z$j$|@GXehrku|b$)o9y@X{rAOCoc=^D`FCP8=n?GJUboIFlU%h!eEo`WB zn})+z4j(yoD5dqYDGlcba{uAOgOt+B)^#bZ`%V6n4|MJ-|5>@{`bQdm(D0+tox`|F zb?)kD^zUQ1hpLquzcEd1>2NqaAW=4@v}v2Qc{AFGcG*4dUps$^T6nr?VM<#r=pCSP zUD|%GQQW!I`yQSl{%hf{$aT=~gg@`p%CAs-;qw zHKo4Ful=Ar6#Tv~8bwX1uk!mpRqur&4-UQ6C~~3HS9#oj$4QN|yjA0yTDfSIU%9RA zha&#!kBy?H)K~eP$CQVHUwpn%)Rg)u{Al#glelg)y0;ne8?|y#&%39sjvdAce~6Dh zn_9VOmB&*a4D_i5ojX%2Z;hXeuTS;)OR9)Fb4TMtt-Kyz`-+u=_hoA3azTYhe>INvx9N|SXRY#BFUT`nH&~Cz1E`g^=AXvT zUypo)f0){RM62;}J>o!dz4?gwN~y2%h>!WQ_WJu-xoDMNxvk@5^Nn%9$JTMFuky|H zO*<^E-Y4JA^R$;-TGl<|(z0APBYF6@sg+OcC5d0TrPr<8lK8R*UHRSA%BS;d*JRvJ z$@oFf$UJ=M)XGoM_)+}T8!~^gXN7`az1gUhi&p!OxY!G2mG&b(`jOSjr|iY|eXjAL z?e-&nsh=7j*C9Uk;D|d`E1%MS%-_8^S%=Vh%%4*$pPSZyohR%6+I8*!+I1^`@cdc( z(SPu!RxVoYKk^6d&noR-y{YZbYUNYf@ADV)wzNyzzqCu+U+Syzci+|PcHdPF`H%Zx z9C5}f^;Lf7QEh)#Y5(G0ZGTp2f2ptXt2Z$v`j-~Wl`KNR!6|FcFh|E1oypZLJ~CEoiF+K=&5)&7_IYJB8>*R-9;e~f>J=U0mt?uzCS_zus1;sgFie8B&R_v^Q#{}GRI z>*;?Jd{6%)KHz`E2mFtCKYktk&+#GubA0i=e*Q-jIwW4H4^@qy^-H|>pN{)q;sgFO!S~$%5+Cpn;sgFcydS@g`(MY0 z_P>q~?SF~){kMIuX=VRQe87K*_v@#l{}3PWAL0Z4Gr{-Ve-j_@FX99KMeh;>o?k7# z_w%3lfd3I6@IT`H`t9g{#0UIug74{n#0UJ3c)$KT?w^SF5_ffU- ze6I?R_cb(@zOSL*f#6Pf2LWv<^;39dz@xwT4#pJ!m-j)cy#Kz&jo0{nj8b3a^*xd1 zy^*Fr`rS&Yukbo<_P#~)zDqM7`aVW&{JFoFcl5#3#zC|aU&ja6W1Nt~7&B8V7p?O8 zo(}r2ad98x5Wm!Wp5Da^tRLb7>xcNj`f+?{{SY5mKaL;gcb-2t-+3M@`A>Wx{~aI7 zU&n{?mw2CVmba#shpqf2K9IlkE@&Wsi4Wv2@qzp$zVR!#uFi*Q)qh*OGMI;s`A2*p z|A-IxFY*3)fqX$9OkIDxe-R(ZKjH)V_r8A@Igo$E2l9{jK>j&C4vc)j0u-r>FcxYrK-gmdoqo^#JR_dbLOf*zt=Q2K%# zLevqVlKqWx5Vp70feZQK%G%TGw?Di-zR^0o)_-}gi>T<)g<)syZWo0z5KaZ${agT` zQOn!^nZJvVfcyYZW?Y3CpiqK0P9+R)ZEm$&c4Y-9&q~y4CQ7`^xX+kxk1@e#%y+0yaPu9ptj-`T7)GiS`nCQm7x+m?ze)o!cd)c<%0)OU;_spEc1 zwbyrCdUi{4Bu|%RYLuL!#P5vHsbrqy+_u~qrP|&31M@x6kes0AQA*yw#P5hN>$y&K z8@6rShg7?zQ$OG1#7msqiR>d(drYsMb>cp(Tk|NT+AW=WuID<{ZFEFWs@(+o%$GN5{JM}l|6(nr+I?Rgo|AJ2LJ#7 literal 0 HcmV?d00001 diff --git a/testdata/drc/drcSimpleTests_au25.gds b/testdata/drc/drcSimpleTests_au25.gds new file mode 100644 index 0000000000000000000000000000000000000000..59dbbe6c97dd909d971fbbed16f491c4680209c3 GIT binary patch literal 8490 zcmbW6!EaSn5XMhi+G1*@1e;3Qu8`n@q%|Rkq67^A2{n>X0~ix9;z}c6SfHSB;R1Iq zT$pGK3ldqdbip5BT(iI(D}#cDn5I!hp`uuMJ%q{2j$6+Z#p-+rLdhpDhYg!E{J%d8 zVd`8_fbcj^DEZX696yB7TSc+F==kr;A#A!@6hg@jv-;Pbb^F1sXF?ddUnBPWdX68$ z^aC>}lOdInbf97oAZY~s-LzHonmTdug@g!r*qZ{QcjAK$aj z?Umi2Icpx{-@@E%97`qt)xcQq9w$Ick zxnTppDDHm^zbKYY!>>_t!z`aSioGClQydl7YQ2$9p6DFa4p8!@{CVkHzduOal?NdA zuhtv&^M0(x1oB1i82eq`{CykzOqMk7@t#jLCNheS^jT7 zxu3x0MfymM_|Mn#d^qd_SLf+JHA_dV`O|Kr}|j!^QZ z`*UCHgwKBXj*^!)W&KCLWxx73If#DcqOT|Z8;tw^-Rsl~?oXX6iU${Kl-%k{tUu!O zKE3{c)SvwqYNY;D>sdbU^@*ST-ID)1COrQ^$qgI$Ugvr5=-)9>BlRD7Tm4V$-+#gN zfYjfGoi(DrTF>g|zT8vyUfAjSLCM?dZ=!$rj_U_`x0|lki2iCltAF^8=Pttk;!gbP__Ln#pW^E%-eck)=_gvQ zKOe^?{jK*^+RPbUyuV0)-Di8qzq7gg>GJ(W{7(OM@qW(5`g8eLeYYr|HzVbKH-&g*gkMn2th}EgR)+fPNtbfi%DEZ#Re+hs3xV_IQtDE3fdw;)1DEU+~ ze|66JtIs>Xg_6(Z`PjXD%El*^AEMvzAM{5k`NJl@#eU4~e>Cp) zw@~u29N*$MSCl_|F!`DN+kD_CIhg0K9P)iDhn%-^SSWcj|IwK5;|}P>c1OvZ`D@#J z-`Y0kt!)=d-ogL4J^z+YdHj~%_4u_=@>9wEBfjhKKhbONaX^@?#qU4j+xt7~@hj2p zK7G=CP@?&yTF>yUeth72N<445XgN3~w6lFZZ+{v0OXPvgKks||g_D(h@=~6^e9Z63 z8z64zca$8=^RW*-B_{kxp4IPpPyOKiQ$J?kh*0vhekA_q-3{G?Z}_LbzZObJN65D0x=D&6(t_-59p&Yuy#(|=vepP%ORa|gv!`Bd2# z=U>9te)hrF_fy0C8u2^r?_z$7_*Spl^1qAuGveFZvhSxJ=g)}WSN=r&zVhc%9KSy1 zrw)FP^JBuNKJ_^Nb?|$fKO??<=k`87CHy|-x685rtNPsPpIy}Ngx^R1OZa{CuY_Or zE%mAH`d0^^*;DfueLJ3?*O|W(e%bdlXIS6sV*ZHu^hV7|nwx}@cg#---{(7@pIUQY r^ZeJr?{WT0_e@A@gCihe4{3Lnpzft>tqz&PJ85rtA literal 0 HcmV?d00001 diff --git a/testdata/drc/drcSimpleTests_au25d.gds b/testdata/drc/drcSimpleTests_au25d.gds new file mode 100644 index 0000000000000000000000000000000000000000..554b845d26679117b5c3bd7e57e6df2e5c560492 GIT binary patch literal 8094 zcmbVR&u>&!6h57{L*<7QlvHe4VS@{j)`TDm5OY%lj? zKMP$U5Gl{|Mb`WxvhIfAW1op^_(6n7xuUnf<)c6Po5&+Si2xDxjn^Vlu2|rQ@cZ}R zhp_l2^hcyzvEn}@dt>eP{L3dTcWXB@ldEMfp0=MHx+=1MYV^>L8ajORdCP$Q?5%b+ z7sB!}cxkwG!6HtiT%(cY-+51D;(Q1|@bEq&rL!>-!zsTen;{Z`Xvo|B6|LXIMetRCzk#|JXhW7v|SIqJ!&!FN>&(N~H$B^<0 zi+sch??K#VZ$_kCG0VsEc#gayCyfuJyu^oIbSZG<340Hba>cCv{Z}nsKy)kOMnoLz z^8!DFKfl3qW-sjqQm&Zg@3}65cmt6y<_$=>Vu5e*+H>9F0KM=Vh;)ok%p>z!pBMS46TXMD14wzPexCoz z{0AcMtOFqYug{D6(LXw41ogr`hW#e*>K`}tF|iRZ!+ZNe_~#PxWk|VBbFbg=VV}hx zh^c?zVnoEhKF{)DFK!ng{NFJik@C{513yvcKcIK6cd>(y^f$`!r-gx|FP@Ec}7Fk}Bh)Ni%VO#?M+_XxKg zo+tVfK586%V7xEw9;93!@b)Ks+?(L>9(6s_kvHxy$B%uB{zJWEjuX+(bzf)nTis#K z)%RR=kMZ83yfOb0{p@of<{j#g2w&>+g8ukC<`C>B@;#0Dnds--1419>9})dfpJ()2 ztdJ+f3|k*QM9Nj<`S1JsY32|64`L1*nAb-B9KSpMyLQLDArt?E@8gfS^$>r@hn+h2 zzm4|NexTJa&U5~E;#=v3&rg5y(D*z3(O&q$yaRXbj&;$(tqcp{_gtY9)x{1Q-2A6 zfckTMn|tgN_|5t&^pE4`>!;qk*blyc9pCEz{%pDawH`D4?)v8*$~|nA`Q!9k%|d^v ze)IYVs^3Ka0QGwz){p9+3DxKRjLy4{_4_kK%7IDz68`d0dv5ut@s^JhDKGIg|ED!} z>uTJf_s6gLok;n*oPN#U37s>0YkWcPk8S#$NcrA8fAX~U$zAAI{1^HiQhqnjhyJBg zrhn;G)89eLPv!aWe`Uh_U)gH@caZXlG9S6adyqTCuY;7&^o8otNiyjsP!cEH#E5r2JfBf5NZo_A=^NXX!iUJ8?@b z-*P$6Upi%WB8TuB`VA>B*>7=2{UQFSyKOHyq&%&^#D4eL?bdlT z1p9&Uq|v`lzr`N8M-Gtt$=4iGp7vkDNBu9JwfbLt%j&;_l%LJVzp5McABeo6eu#*R zo#*)a?Az9VK*S$hB63=v`}v>P55LiW6>9&%fAn94l&Afd@TVtLpXRwj)sOyz{t7A2 z<{x#V`{Jz{{{m0H6Dhxy_aAi!KUsgU8~TBiD|-JgCH>d<{iTQd+wnENx^v;K2V(E* zVSi2de4c#%{!rK-9Ur=}ADRvP{f&D_X8(13t=szVF0iA={nzo$XXt_N@S%tO)A6slGj>n(vHvCf0ro$~w|k?{{jH0SIalprz3pEKA9J(M z{i}=L=l*rY$A5tR$MJ3MbIx<_6De=Z|Aarl{gv>my@7iI_jV%X>Hg5g@ALjm_ygSk zj*tDq>c4ycpd6UYU&pt)>vR8ceDt5~d424!34eh7(ebT*`rKa~U*~5Z`?LP9>Bxxu E4`5&x$p8QV literal 0 HcmV?d00001