diff --git a/README.md b/README.md new file mode 100644 index 0000000..39c1f0a --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +# Package UUEncode + +A short and sweet Go library that supports decoding uuencoded things. + +For more information on what uuencoding is/how it works, check out [this wikipedia article](https://en.wikipedia.org/wiki/Uuencoding). + +**Important Note:** This package currently only supports _decoding_ uuencoded contents (because...well...that's all we need here at Polygon.io for now :shrug:). +Contributions are welcome, if you'd like to implement an `Encoder` struct and create a PR we'd be overjoyed :D + +uuencoding is an old, rarely unused format at this point and the standard isn't very strict. +There are lots of little variations in different implementations. + +This particular implementation is geared towards decoding binary files within SEC filings. +It implements the behavior described in the wikipedia article linked, so it should be relatively portable. +This implementation also adds some extra features to clean up input that doesn't quite conform to the expectations of that format. + +There are tests ensuring this package works decoding standard input, input encoded via the `uuencode` utility on macOS, and input encoded in the style that the SEC follows. + +## Examples + +For examples, check out the test files ([decode](./decode_test.go)) \ No newline at end of file diff --git a/decode.go b/decode.go new file mode 100644 index 0000000..039e1ce --- /dev/null +++ b/decode.go @@ -0,0 +1,124 @@ +package uuencode + +import ( + "bufio" + "bytes" + "encoding/base64" + "fmt" + "io" + "strings" +) + +const ( + // StandardCharset is the standard charset for uuencoded files: ASCII characters 32 - 95. + StandardCharset = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" + + // AlternateCharset is the same as the standard charset, except that the space character is replaced by backtick. + // This encoding is non-standard but used occasionally. (Like in the BSD uuencode implementation). + AlternateCharset = "`!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" +) + +// Decoder encapsulates functionality for decoding uuencoded content. +// To create a Decoder, use the helper functions NewStandardDecoder or NewDecoder(charset). +type Decoder struct { + // encoding is used to decode individual lines within the encoded text. + encoding *base64.Encoding + + // paddingChar is used to pad lines that have had their padding chopped off for one reason or another. + paddingChar string +} + +// NewStandardDecoder returns a Decoder that uses the StandardCharset. +func NewStandardDecoder() Decoder { + return NewDecoder(StandardCharset) +} + +// NewDecoder returns a decoder using the given charset. +// See StandardCharset and AlternateCharset for common values. +// Note: the provided charset must be a valid base64 charset, otherwise attempts to Decode may panic. +func NewDecoder(charset string) Decoder { + return Decoder{ + encoding: base64.NewEncoding(charset).WithPadding(base64.NoPadding), + paddingChar: string(charset[0]), // Padding char is just the first character in the charset + } +} + +// DecodeToBytes is a convenience function for decoding a reader when you just want all the decoded contents in memory in a byte slice. +// See Decode for more info. +func (d Decoder) DecodeToBytes(reader io.Reader) ([]byte, error) { + var buf bytes.Buffer + if err := d.Decode(reader, &buf); err != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +// Decode decodes the uuencoded contents (as described here: https://en.wikipedia.org/wiki/Uuencoding#Encoded_format) +// of reader and writes the decoded bytes to the given output writer. +// This function assumes there is only one encoded file in the reader, it will ignore anything past the end of the first encoded file. +func (d Decoder) Decode(reader io.Reader, output io.Writer) error { + scanner := bufio.NewScanner(reader) + + lineNumber := 0 + for scanner.Scan() { + lineNumber++ + + if scanner.Err() != nil { + return fmt.Errorf("error while scanner reader: %w", scanner.Err()) + } + + line := scanner.Text() + + // We don't care about the begin line, we also don't care about empty lines + if strings.HasPrefix(line, "begin") || line == "" { + continue + } + + // When we find the first end line, we're done. + if line == "end" { + return nil + } + + // If it's not a begin or end line, first check the line length character. + // If it's the special character backtick (`), the line is empty and we should skip it + lengthChar := line[0] + if lengthChar == '`' { + continue + } + + // uuencoding adds 32 to the lengthChar so its a printable character + decodedLen := lengthChar - 32 + + // Some encoding schemes don't use the special character for empty lines. + if decodedLen == 0 { + continue + } + + // The formatted characters are everything after the length char. + // Sometimes padding is omitted from the line, so we have to make sure we add it back before decoding. + expectedLen := d.encoding.EncodedLen(int(decodedLen)) + encodedCharacters := d.padContentLine(line[1:], expectedLen) + + decoded, err := d.encoding.DecodeString(encodedCharacters) + if err != nil { + return fmt.Errorf("error decoding line %d: %w", lineNumber, err) + } + + // Write the decoded bytes to the output writer + if _, err := output.Write(decoded[:decodedLen]); err != nil { + return fmt.Errorf("error writing decoded bytes to writer: %w", err) + } + } + + // If we made it out of the loop, it means we never saw the 'end' line + return fmt.Errorf("malformed input; missing 'end' line") +} + +func (d Decoder) padContentLine(line string, expectedLen int) string { + for len(line) < expectedLen { + line += d.paddingChar + } + + return line +} diff --git a/decode_test.go b/decode_test.go new file mode 100644 index 0000000..5e9f509 --- /dev/null +++ b/decode_test.go @@ -0,0 +1,58 @@ +package uuencode + +import ( + "io" + "os" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestDecodeToBytes(t *testing.T) { + t.Run("standard encoding", func(t *testing.T) { + input := "begin 644 cat.txt\n" + + "#0V%T\n" + + "`\n" + + "end" + + decoder := NewStandardDecoder() + + results, err := decoder.DecodeToBytes(strings.NewReader(input)) + require.NoError(t, err) + assert.EqualValues(t, "Cat", string(results)) + }) +} + +func TestDecodeFiles(t *testing.T) { + t.Run("BSD/Alternate style encoding", func(t *testing.T) { + // polygon.uu was uuencoded using the `uuencode` utility on macOS + decodeFile(t, NewDecoder(AlternateCharset), "test_data/polygon.uu", "test_data/polygon.jpg") + }) + + t.Run("standard/SEC style encoding", func(t *testing.T) { + // polygon.sec.uu was encoded in the same style that the SEC uses when disseminating binary files in filings + decodeFile(t, NewStandardDecoder(), "test_data/polygon.sec.uu", "test_data/polygon.jpg") + }) +} + +func decodeFile(t *testing.T, decoder Decoder, encodedFilename, decodedFilename string) { + encodedFile, err := os.Open(encodedFilename) + require.NoError(t, err) + + defer encodedFile.Close() + + decodedBytes, err := decoder.DecodeToBytes(encodedFile) + require.NoError(t, err) + + expectedFile, err := os.Open(decodedFilename) + require.NoError(t, err) + + defer expectedFile.Close() + + expectedBytes, err := io.ReadAll(expectedFile) + require.NoError(t, err) + + assert.Equal(t, expectedBytes, decodedBytes) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..ba440c3 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/polygon-io/uuencode + +go 1.16 + +require github.com/stretchr/testify v1.7.0 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..acb88a4 --- /dev/null +++ b/go.sum @@ -0,0 +1,11 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/test_data/polygon.jpg b/test_data/polygon.jpg new file mode 100644 index 0000000..21616cd Binary files /dev/null and b/test_data/polygon.jpg differ diff --git a/test_data/polygon.sec.uu b/test_data/polygon.sec.uu new file mode 100644 index 0000000..f3a2674 --- /dev/null +++ b/test_data/polygon.sec.uu @@ -0,0 +1,349 @@ +begin 644 polygon.sec.jpg +M_]C_X 02D9)1@ ! 0 D "0 #_X0">17AI9@ 34T *@ @ !0$2 , +M ! $ $: 4 ! 2@$; 4 ! 4@$H , ! ( (=I +M 0 ! 6@ "0 0 ) ! .2A@ ' $@ (2@ +M @ $ 0 1J@ P $ 0 0X 05-#24D !38W)E96YS:&]T +M_^$)(6AT=' Z+R]N&%P+S$N,"\ /#]X<&%C:V5T(&)E +M9VEN/2+ON[\B(&ED/2)7-4TP37!#96AI2'IR95-Z3E1C>FMC.60B/SX@/'@Z +M>&UP;65T82!X;6QN#IX;7!T:STB6$U0 +M($-O0 +M +M &UL=6, )@ QH +M ", * M #( +M-@ [ $ 10!* $\ 5 !9 %X 8P!H &T <@!W 'P @0"& (L D "5 )H GP"C +M *@ K0"R +< O #! ,8 RP#0 -4 VP#@ .4 ZP#P /8 ^P$! 0&!YD'K >_!]('Y0?X" L('P@R"$8(6@AN"(((E@BJ"+X(T@CG"/L)$ DE +M"3H)3PED"7D)CPFD";H)SPGE"?L*$0HG"CT*5 IJ"H$*F JN"L4*W KS"PL+ +M(@LY"U$+:0N "Y@+L O("^$+^0P2#"H,0PQ<#'4,C@RG#, ,V0SS#0T-)@U +M#5H-= V.#:D-PPW>#?@.$PXN#DD.9 Y_#IL.M@[2#NX/"0\E#T$/7@]Z#Y8/ +MLP_/#^P0"1 F$$,081!^$)L0N1#7$/41$Q$Q$4\1;1&,$:H1R1'H$@<2)A)% +M$F02A!*C$L,2XQ,#$R,30Q-C$X,3I!/%$^44!A0G%$D4:A2+%*T4SA3P%1(5 +M-!56%7@5FQ6]%> 6 Q8F%DD6;!:/%K(6UA;Z%QT701=E%XD7KA?2%_<8&QA +M&&48BABO&-48^AD@&449:QF1&;<9W1H$&BH:41IW&IX:Q1KL&Q0;.QMC&XH; +MLAO:' (<*AQ2''LP>%AY 'FH>E!Z^'ND?$Q\^ +M'VD?E!^_'^H@%2!!(&P@F"#$(/ A'"%((74AH2'.(?LB)R)5(H(BKR+=(PHC +M."-F(Y0CPB/P)!\D321\)*LDVB4))3@E:"67)< ^(#Y@/J ^X#\A/V$_HC_B0"- +M9$"F0.=!*4%J0:Q![D(P0G)"M4+W0SI#?4/ 1 -$1T2*1,Y%$D5519I%WD8B +M1F=&JT;P1S5'>T? 2 5(2TB12-=)'4EC2:E)\$HW2GU*Q$L,2U-+FDOB3"I, +M%W)7AI>;%Z]7P]?85^S8 5@5V"J +M8/QA3V&B8?5B26*<8O!C0V.78^MD0&249.EE/6629>=F/6:29NAG/6>39^EH +M/VB6:.QI0VF::?%J2&J?:O=K3VNG:_]L5VRO;0AM8&VY;A)N:V[$;QYO>&_1 +M<"MPAG#@<3IQE7'P,QY*GF)>>=Z1GJE>P1[8WO"?"%\@7SA?4%]H7X!?F)^PG\C?X1_Y8!' +M@*B!"H%K@%JX8.AG*&UX<[AY^(!(AIB,Z) +M,XF9B?Z*9(K*BS"+EHO\C&.,RHTQC9B-_XYFCLZ/-H^>D :0;I#6D3^1J)(1 +MDGJ2XY--D[:4()2*E/257Y7)EC26GY<*EW67X)A,F+B9))F0F?R::)K5FT*; +MKYP0)ZNGQV?BY_ZH&F@V*%'H;:B)J*6HP:C=J/FI%:DQZ4X +MI:FF&J:+IOVG;J?@J%*HQ*DWJ:FJ'*J/JP*K=:OIK%RLT*U$K;BN+:ZAKQ:O +MB[ L'6PZK%@L=:R2[+"LSBSKK0EM)RU$[6*M@&V>;;PMVBWX+A9N-&Y2KG" +MNCNZM;LNNZ>\(;R;O16]C[X*OH2^_[]ZO_7 <,#LP6?!X\)?PMO#6,/4Q%'$ +MSL5+QHM\IWZ_@-N"]X43AS.)3XMOC8^/KY'/D_.6$Y@WFENV<[BCNM.] [\SP6/#E\7+Q__*,\QGS +MI_0T],+U4/7>]FWV^_>*^!GXJ/DX^P 3,T )F: F9@ #UP % / !4.P ",S, C,S (S +M,P 1 #]D?__^Z/___VC +M #VP P'EM;6]D $*P $&U0C7J#A(6& +MAXB)BI*3E)66EYB9FJ*CI*6FIZBIJK*SM+6VM[BYNL+#Q,7&Q\C)RM+3U-76 +MU]C9VN'BX^3EYN?HZ>KQ\O/T]?;W^/GZ_\0 'P$ P$! 0$! 0$! 0 +M $" P0%!@<("0H+_\0 M1$ @$"! 0#! <%! 0 0)W $" Q$$!2$Q!A)! +M40=A<1,B,H$(%$*1H;'!"2,S4O 58G+1"A8D-.$E\1<8&1HF)R@I*C4V-S@Y +M.D-$149'2$E*4U155E=865IC9&5F9VAI:G-T=79W>'EZ@H.$A8:'B(F*DI.4 +ME9:7F)F:HJ.DI::GJ*FJLK.TM;:WN+FZPL/$Q<;'R,G*TM/4U=;7V-G:XN/D +MY>;GZ.GJ\O/T]?;W^/GZ_]L 0P " @(" @(# @(#! ,# P0%! 0$! 4'!04% +M!04'" <'!P<'!P@(" @(" @("@H*"@H*"PL+"PL-#0T-#0T-#0T-_]L 0P$" +M @(# P,& P,�D'"0T-#0T-#0T-#0T-#0T-#0T-#0T-#0T-#0T-#0T-#0T- +M#0T-#0T-#0T-#0T-#0T-#0T-_]T ! 2_]H # ,! (1 Q$ /P#SNBBBO]1# +MX\**** "BBB@ HHHH **** "BBB@ HHHH **** "BBB@ HHHH **** "BBB@ +M HHHH **** "BBB@ HHHH **** "BBB@#__0\[HHHK_40^/"BBB@ HHHH ** +M** "BBB@ HHHH **** "BBB@ K[F^"W[']UXS\*7/B3Q[/<:1_:-L?[(@0#S +MD+=]D^)'Q*M/W?RS:7I4Z_>[K/<*>W=(S +MU^\W& ?T%O%%OY-Q#\T4JY,-Q"20LL3$#?EGTO29E_%)[A3^:1GV+=A4O[,7[,'D_9/B1\2K3]Y\LVE +MZ5.OW>ZSW"GOW2,]/O-S@#ZY^+OQ>\,_!_PR^MZX_G7K%5/\T^)?B;BMA,(HK +MVU;8[G5?$VC:-J6EZ-?7"K?ZS,\%C;+S+,8D,DC!?[D:*6=CP.!U(!R_B'XE +M7P=X$U_Q06"MIFG7-Q'GO*D9\M?^!/@?C7PK^RWK7B;XO?&K7_B?XNF^T2:7 +MIWDP(N1#:M=OMCCB4D[46-)1CJ22Q)))/L?[:7B?^Q/@^=&C?$NO:A;VI4<' +MR82;AS]-T:*?]ZOR&KP&L'Q1@^'9RYZC=/VMMDY/FDEY*%M7N[O1:+N6)YJ, +MJJVUL>3_ +,/[3YE-K\./B5>$R$K#I>JSMG=GA8+ASW[1R'K]UN<$_7WQ;^$ +MGAGXO^&7T'7D\JYBW/8WZ*#-:3$?>7IN1L .A.&'H0K#\)J_1K]F']I[S/LG +MPV^)-W\_RPZ5JL[?>[+;W#'OVCD/7[K$X/FE&. +MZ?6<%_Z5':U]+71Q83%J2]C6/A[XB?#OQ-\,?$UQX7\46_E7$7S12KDPW,)) +M"RQ-@;D;'U!R" 00.&K]V?BW\)/#/Q?\,OH.O)Y5S%N>POT4&:TF(^\O3&?B9AN)L-["O:&*@O>CTDOYH^7=;Q?E9G+B\(Z3NMCAJ***_53B"BBB +M@ HHHH **** "BBB@ HHHH **** /__2\[HHHK_40^/"BBB@ HHHH **** " +MBBB@ HHHH *_1_\ 9B_9@^S?9/B1\2K3]]\LVEZ5.O\ J^ZSW"G^+ND9^[]Y +MN< /_9B_9@^Q_9/B1\2;3_2/EGTO2IE_U7=9[A3_ !]TC/W?O-\V OUC\7_C +M!X9^#WAIM:UMO/O9PR:?IZ,!+=2@?CMC7(+N1A1ZL54_S/XE^)F)S'$_ZK\+ +MWG.;Y92CN^\8OM_-+:U];7;]?"8117MJPOQ>^+_AGX/^&FUO6W$]Y.&2PT]& +M FNI0.@Z[8UR"[D84>K%5/XP_$#X@>)OB7XFN?%/BFY\^YG^6.-ZG.V.-VK6GBIKWI=(K^6/EW>\GY62Y<7BW6=EL?K%^Q'X +M8_LGX5W?B*5,2Z[J4KHW]ZWM0(5'X2"7\Z\(_;L\3_;?&?A_PG$^4TNPDNY +M#P);Q]N#[A(5(]F]S7W_ /"?PQ_PAOPU\->&F3RY;+38%G7IBX=0\WYR,U?C +MQ^T#XG_X2[XQ^*M65]\27[V<)[&*R MU(]F\O=^-?E'AK_PN^(&-SIZQASN+ +M]7R0_P#)+_<=N+_=X:-/N>.4445_59XI^CG[,'[3OF_9/AM\2+O]Y\L.E:I. +MWWNRV\['OVC<]?NMS@GZ]^+?PD\,_%_PR^@Z\GE7,6Y["_109K28C[R]-R-@ +M!T)PP]"%8?A-7Z.?LP_M/>=]D^&WQ)N_WGRPZ5JL[?>[+;W#'^+M'(>OW6YP +M3_-'B9X9XG 8G_6CAB\)P?-*,=T^LX+M_-':U]+71Z^$Q:DO8UCX<^(GP[\3 +M?#'Q-<>%_%%OY5Q%\T4JY,-S"20LL38&Y&Q]0<@@$$#AJ_=GXM_"3PS\7_#+ +MZ#KR>5PKVABH+WH])+^:/EW6\ +M7Y69RXO".D[K8X:BBBOU4X@HHHH **** "BBB@ HHHH **** /_3\[HHHK_4 +M0^/"BBB@ HHHH **** "BBCKP* "OTF_9B_9@_L_[)\2/B3:?Z5\LVEZ7,O^ +MI[K/<*?^6G=$/W/O-\V K_V8OV8/[,^R?$?XDVG^F?+-I>ES+_J.ZSSJ?^6G +M=$/W.K?-@+]3_&+XQ>&O@[X:;6-887%_)7B7B\8OM_-+:U];7;]?"8107MJPOQA^,/AKX. +M^&FUG66%Q?7 9-/T]& ENI0/QVQKD%W(PHXY8@'\8O'WC[Q+\2O$MSXI\4W) +MGNISM1%R(H(@3MBB7)VHN>!U)R22Q)*>/?'OB7XD^);GQ3XIN3<7=P<(@R(H +M(@3MBB7)VHN>!U)R22Q)/&5^C>&GAIAN&<-[:M:>*FO>ET2_ECY=WO)^5DN3 +M%XMUG9;!7HWPA\,?\)C\3_#/AQD\R*[U*#SU];>)O,F_\AJU>&/[ +M5^*%]XCE3,6A:;(4;'W;B[81)^I&)^FOC?Q%'X1\&ZWXHD(QI6GW-V ?XGBC9E7ZLP 'N:_G_EEDFD>:9B +M[R,69F.26)R23ZDU^OG[97B;^PO@S<:9&^V;7;VVL0 ?F\M";AS],1;3_O8[ +MU^0%?DGT>,H]CD^(S"2UJSLO2"_SE+[CNS2=ZBCV"BBBOZ#/+"BBB@#]'?V8 +M/VGO/^R?#;XD7?[WY8=*U2=OO]EMYV/\7:-SU^ZW."?KSXM_"3PS\7_#+Z#K +MR>5OA,6I+V-8^&OB)\._$WPP\37'A?Q3;^5/%\T4JY,-S"2=LL38&Y&Q] +M0<@@$$#AJ_=KXM?"7PS\7O#+Z#KR>5<1;GL;Y%!FM)B/O+_>1L .A.&'H0"/ +MQ?\ B+\._$WPP\37'A?Q1;^5/%\T,RY,-S"20LL3$#,DTUY/1C3L[H_H3\. +MZ_IGBG0K#Q'HLHGL=2MX[F!QW209 ([,.A'4$$&OQI_::M/&=E\8=:A\:W3W +MLK.)+"4C;&=/8OH P' +M+5_(_!\8\#\SJ^[&;6JC)WA*_1-^[+I>_\I[E?_:,/SQW1^1M%%%? +MU\>$%?JM^PYX8_LSX;:GXFE3;+K>I%4;'WH+-0B_E(THK\J:_=[X,>&/^$.^ +M%7A?P\R>7+;Z=#).N,8GN!YTP_[^.U?A'T@S>]?!->W? +MM'>)_P#A*_C3XHU!'WPVUX=/AP(U^A^'>4_V;PW@\(U9 +M\BD_67O/\78Y<5/GJRD%%%%?:'.%%%% !5BTM+J_NH;&RB>>XN)%BBBC4N\D +MCG"JJCDL2< #J:KU^G/[)/[/O]@VMO\ %/QE;XU*ZCW:1:2KS;0R#_CX<'I+ +M(I^0?PH<_>;Y?D.-N,<)PWELL?B=9;0CUE+HO3JWT7G9/?#T)59\J/J+X,Z# +MXS\-?#C1]'\?7YU#6(8?WK$AFA0_:G>SZCJ$SW-U=2/---*Q9Y)'. +MYF8GDDDY)K\"\'>"\1FN9RXMS"/)#FDX**Y5*3;NTE]B.J2ZO1Z)I^GC\0H0 +M]A$JT445_5AXH4444 %%%% !1110 4444 ?_U?.Z***_U$/CPHHHH **** " +MBBB@ HHHH VO#FOZIX5UZP\2:+*8+[3;B.Y@?L'C.0".ZGHPZ$$@U^[?P]\: +MZ3\2O!6F>+M,"FWU* &6$G<8I1\LL+>I1P5]QST(K\"J^WOV+_BO_P (WXIF +M^&^KS;=/U]_-LBQPL6H*N-H[#ST 7W=4 ZFOQ+QOX,_M7*/[2PT?WV'N_-P^ +MTOE\2]';<]#+\1R3Y'LSQK]HOX5M\*OB/=Z=9Q%-&U+-]IC?PK#(?FASZPOE +M<==NTGK7@U?M1^TK\*1\4_AS$W&7^L&21=:5Z]*T9]W_++_MY;_WDS/&T/95--F=U\,/#/_"9 +M?$/P[X89-\>H:C;Q3#K^XWAIC^$88U^Z'BS7H/"OA;5_$MQCRM*L;B\8'H1! +M&SX_'&!7Y;_L3^&/[8^+,VO2)F+0=.FF5O2>YQ @_&-Y#^%?8W[8/B?_ (1[ +MX*W]E&^R;7+JVTY,==I;SI/P,<3*?]ZOR3Q>;SKC+ 9#'6*Y4_)SE>7_ )(D +MSNP/[O#RJ?UH?CYW\.Z:ROJ5TO!;/*V\1_P">DF.3_ N6/.T-YFSN-O(#BOU5) !). .235+3--L-&T^VTG2K>.UL +M[.)(8((EVI'&@PJJ!T KQ/]I;QW_P (#\(=9OH)/+OM33^R[/!PWFW0*LRG +ML4B#N/=17\*<1<0YAQOQ#3ALIR4*<>D4W^?63_1)+Z.E2CAZ3_$_*7XW^/&^ +M(_Q/UWQ,DADLVN#;6/.5%I;_ +N(KZ;P-Y']YC7D]%%?WCEN HX'"4\'AU:$ +M(J*]$K(^;G)RDY/J%%%%=I(4444 %%%% !1110 4444 ?__6\[HHHK_40^/" +MBBB@ HHHH **** "BBB@ JQ:75S8W4-]9RM#<6\BRQ2H=K)(A#*RD="",@U7 +MHI2BFK/8#]T?@C\3;7XK_#S3O$ZE1?H/LNI1+_RSO(@-_'97!$BCLK =0:_- +MS]K;X4#X?_$!O$6E0[-&\3-)=1A1\D-V#F>+C@ DB11QPQ X6JW[)_Q7_P"% +M=_$./1=4FV:)XD,=G<;CA(;G.+>;T #,48\#:V3]T5^F/QI^&MK\5OA[J/A6 +M0*MX5^TZ=,W_ "RO(@3&<]@V2C'^ZQ[U_(\E+P\XVNM,'7^Y0D_SIR^?+_B/ +M<_WK#_WE_7XGSI^POX8_L_P#K?BF5-LFL:B($..L%DG!!_ZZ2R#\*\U_;Q\3 +M^=K7ACP=$_%K;3ZE,H[FX?RHL^ZB)_\ OJOM?X)>$9O OPI\->&KN(P75O9+ +M+=1M]Y+FY)FE5O=7T&V>\U"_E6&WACZL[?H !R2< $D@#-15JPIP=2H[12NV]$D +MMVQI7T1U7PQ^&^O_ !4\76OA/0$PTI\RYN64F.UMU(WROCL,X R-S$*.37[9 +M^"O!OA?X6>#K?P[HJI::;IL3233RD*78#=+/,YP-S8RQ. ,#"@ <;\#?@WI +M/P<\(II4.RXU>\VS:I>J.99@.$0GGRH\D(.,\L0"QKYK^._Q5N_BCX\T[]GG +MP!WT=KK=] BRJ-Z \[&7.#D#\UOVX/'?]L>-M-\"6DF;?0;?S[E0>/M= +MV P!'?9"$(/^V:_2Z[N='\'>&IKN0+::7HEBSD+]V*VM8\X'LJ+Q7X)^+_$M +M]XR\4ZKXJU+_ (^-5NYKIUSD)YC$A ?[J#"CV I^ _#U+&9[7S>,;4J*:A?^ +M:=TM>K4;W\VF+,JKC34.K._[U!R>[J_;%?C!7T'^S'\0+GP%\6](+3>7I^M2K +MI=\A/R%+A@L3'L#'+M;=V7<.A-?F'BUPC'/.44UVBDVOO;?W'5FK=XKH%%%%?TJ>2.1'D=8XU +M+,Q"JJC))/0 =R:_7+]E[X )\,]&7Q=XH@!\4:I$/D89^P6[X/E#_IJW!D/; +M[@X#%O'OV1?V?=QMOBUXTMN!B30[25>I[7;J?_(.?]_^X:^G_C]\;-.^#GA0 +MW$6RXU_40\>F6C03_>;"C&21_,/BIQMBL[Q\>#^'O> =,?P%X1N<>(]1B_P!)GB/S:?;. +M.H(^[-(/N=U7Y^"4)\7_ &&? AU#Q%K/Q$O8]T6F1?V?9LPR#2( +M!3[2U\,ZMJVI:]J=UK.L7$EW?7LKSW$\IR\DCG+$_C^ [5^VWP \"?\ "N_A +M1H>@SQ^7?30_;KX$8;[3=?.RM[Q@K']$JN-LLPO!'!?]D85WKXEJ,Y=96UF_ +M\*7NI=%+NVQ8>;Q&(YWLCR3]L_QW_P (S\,(_"]K)MO/$]P(" <,+2WQ),1] +M6\M#ZAS7Y)U].?M:^._^$S^+U_8VTF^Q\.H-+AP?E,L9+7#8]?-+(?4(*^8Z +M_4/"/AS^R.&J$)JTZG[R7K+9?*/*O6YQXZKSUGY:!1117Z8<@4444 %%%% ! +M1110 4444 %%%% '_]#SNBBBO]1#X\**** "BBB@ HHHH **** "BBB@ I\< +MDD4BRQ,4="&5E."".00>Q%,HH: _?#X8>+T\>_#[0/%RD%]2L8I)]O1;A1LG +M4?[LJL/PK\;_ (]^#/\ A!/BWXCT*)-EJUVUY: #"_9[L>N/_ &[O!FV3PY\0+>/A +M@^DW;^XW36_YCSOR%?REX?O_ %9\0,5D4M*=7F4?_2Z?_DMUZL]K%?OL,JG5 +M?TS\[:^M/V7_ ( 2?$[6AXK\30$>%M+E&Y&&/M]PF"(1_P!,UX,I[_='))7Y +M+K]LOV8 !\"/"0 Q_H\YX][F:OU3QEXIQF29!SX%VG5DH>ED^E[ +M[V.+ 48U*OO=#N_B+\0/#GPJ\'W/BC76$=M:J(K:VCPKW$Q'[N"(>K8^BJ"Q +MX!K\2/B%X^\0?$OQ5>>+?$DWF7-RV(XU)\JWA4G9#&#T1 ?J3ECDDD^\?MB^ +M+M=UGXQ:AX9O;@MIF@1VT=E;CA$-Q;0SRN1W=F?!;^ZJCM7RC7G^#7 >'RC+ +M(9M5M*O7BI7_ )822:BO-Z.3[Z;*[O'XESFX+9'M?[/7@3_A8?Q9T/1IH_,L +M;67^T+X$97[-:D.5;VD?;'_P.OV&^)WC.#X>^ =<\83E=VFVCO"K='N'^2%# +M_O2LH_&ODK]AKP)_9WAC5_B#>1XFU>86-FQ'/V:V.9&4^CRG:?>*LK]NKQW] +MGT[0_AS9R8>[J#@^5'F.!3ZAG\QOJ@K\WXU;XM\0*&20UHT6HR[:>]4] +M']CU2.K#_N,,ZG5_TC\WKFXGO+B6[NI&EFG=I)'8Y9GY).34-%%?U@D +MDK(\4****8!1110 4444 %%%% !1110 4444 ?_1\[HHHK_40^/"BBB@ HHH +MH **** "BBB@ HHHH **** /I']E#QE_PB'QGTF*9]EKKJOI,_/!-Q@P_CYZ +MQCZ$U^FG[0?@S_A.OA#XBT:*/S+J&V-]: #+>?9_O0J^[A2G_ J_$.SN[G3[ +MR"_LY#%<6TB312+U22,AE8>X(S7[\>!_$]MXU\&Z-XKML>7JUC#107 +M3ZHV5/N*_ESQTP57+,YP/$N%6J:3_P 4'S1OZIM>D3V,NDITY4G_ %<_G^K] +ML_V8O^2$>$O^O:?_ -*9:_)GXR>#?^$ ^)WB+PLB>7;VMZ[VHQQ]EGQ+"!ZX +MC=0?<&OUF_9B_P"2$>$O^O:?_P!*9:]GQZQM+&<+X/%T'>$ZD9+T=.;7X,C+ +M8N-:47T7ZGYJ_M8?\E_\5?73_P#TAMZ\#T[3[S5M0M=*T^,S75[-';P1KU>6 +M5@J*/F_5^SC9?-V7S.2=-SQ#@NK?YGZH +M>!/"EGX$\&:/X2L]OE:39Q0,XX#R*,R2'W=RS'W-?BO\;_'1^(WQ0U[Q/&^^ +MTDN#;V7.1]DM_P!W$1Z;U7>1ZL:_5O\ :6\=_P#" _"'6;Z"3R[[4T_LNSP< +M-YMT"K,I[%(@[CW45^)M?EG@!DM2M+%\1XK6DQ+Z6M +M[F1?_(HE_,5^4]?4_P"Q]XS_ .$6^,-IID\FRT\16\FG/D_*)?\ 6PGZETV# +M_?K\U\7,B_M3A?$0BKSIKVD?6&K^^/,OF=>!J>AZQ^W9X-^S:WX?\>VT +M>$O8'TVZ8# $L!,D)/J71W'T2OK3]F+_ )(1X2_Z]I__ $IEIO[3/@S_ (37 +MX-:]:11^9=Z;&-5M>,D/9Y=\#N6A\Q1[M3OV8O\ DA'A+_KVG_\ 2F6OYGS? +M/OK_ (=X7#3?OT*_)\N2O"GRXJ3[H_-7]K#_DO_ (J^NG_^D-O7 +MWM^Q[X$_X1+X30ZW=1[+[Q-,;]R1AA;+\ENOT*@R#_KI7QQ\<#_=1>*^O\3,_E#A')\BH:SJTJ4I);V4(J*^._P"V/&VF^!+23-OH%OY]R >#=W8# $?[$(0C_?-?#U='XO\ $M]XQ\4Z +MKXJU(_Z1JMW-=.,Y">8Q(0?[*#"CV KG*_HW@[((Y+DN'RU;PBK^K[2HYA1117TQB%%%% !1110 4444 %%%% !1110 4444 ?_T_.Z***_ +MU$/CPHHHH **** "BBB@ HHHH **** "BBB@ K1TC5+S0]6LM:TY_+N]/N(K +MJ!_[LL+AT/X,!6=14SA&<7":NGN"9_0;X=UK3_%_AC3M?M562SUBRAN51L,/ +M+N(PVUOH#@CUXKG?A;X3;P+X'L?"1SLTR:]BA)Y+0&ZF:%C[M&5)^M>!?L7> +M,_\ A(?A2_ARXDW7/AN\>W )RWV:XS-$3[;C(H]DKZ^K_.?BC U\FQ^+R-OW +M(U+^O+S8=*BT^PLV(X-S< +M6%LTK*?5(@%/M+6;^VAX[_X1GX8Q^%K63;>>)[@0$ X86EOMDF(^K>6A]0QK +MZUM=/M+*:[GMHPDE],+B=AU>01I$&/OLC5?H*_'K]K3QW_PF?Q>O[*VDWV/A +MU!I<(!X,L1)N&QZ^:63/<(*_2/#?#U.)^*L+6KK]UA:=/3_KU&,8KYS]ZWJ< +MF+:HT6ENV_Q/F2BBBO[2/ "BBB@ HHHH **** "BBB@ HHHH **** "BBB@# +M_]3SNBBBO]1#X\**** "BBB@ HHHH **** "BBB@ HHHH **** /KS]B_P 9 +M_P#"._%=O#MQ)MMO$EI); $X7[3;YFB)]]HD0>[U^N%?SW^&=>O/"WB+3/$N +MGG%SI=W!>1#AV.5^)_C.#X>^ -<\83%=VG +M6CO K='N'^2!#_O2LH/L:_!6XN)[NXENKEVEFF=I)'8Y9GJ U^;5?I?@)PY]1R*68U%[ +M]>5_^W(W4?O?,_1HY,RJ\U3D70****_=#S@HHHH **** "BBB@ HHHH **** +M "BBB@ HHHH _]7SNBBBO]1#X\**** "BBB@ HHHH **** "BBB@ HHHH ** +M** "OV#_ &/_ !H/$_P=MM-N9,W/ARXET^3<>?)_UL+?[H1]@_W*_'RO9/A= +M\6M0^&^@>--'L]^?$NDBSA9./+N0X029[;8)9B".=VWZC\X\4>$:G$62_5*' +M\2,XRC]_++Y#KJE4YGL4/C9XZ/Q&^)^O>*(Y"]I+#PZM"$5%>B5D17AI9@``34T`*@````@`!0$2``,` +M```!``$```$:``4````!````2@$;``4````!````4@$H``,````!``(``(=I +M``0````!````6@````````"0`````0```)`````!``.2A@`'````$@```(2@ +M`@`$`````0```1J@`P`$`````0```0X`````05-#24D```!38W)E96YS:&]T +M_^$)(6AT='`Z+R]N&%P+S$N,"\`/#]X<&%C:V5T(&)E +M9VEN/2+ON[\B(&ED/2)7-4TP37!#96AI2'IR95-Z3E1C>FMC.60B/SX@/'@Z +M>&UP;65T82!X;6QN#IX;7!T:STB6$U0 +M($-O0`````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````````&UL=6,`````````)@````QH +M`",`*``M`#(` +M-@`[`$``10!*`$\`5`!9`%X`8P!H`&T`<@!W`'P`@0"&`(L`D`"5`)H`GP"C +M`*@`K0"R`+<`O`#!`,8`RP#0`-4`VP#@`.4`ZP#P`/8`^P$!`0&!YD'K`>_!]('Y0?X"`L('P@R"$8(6@AN"(((E@BJ"+X(T@CG"/L)$`DE +M"3H)3PED"7D)CPFD";H)SPGE"?L*$0HG"CT*5`IJ"H$*F`JN"L4*W`KS"PL+ +M(@LY"U$+:0N`"Y@+L`O("^$+^0P2#"H,0PQ<#'4,C@RG#,`,V0SS#0T-)@U` +M#5H-=`V.#:D-PPW>#?@.$PXN#DD.9`Y_#IL.M@[2#NX/"0\E#T$/7@]Z#Y8/ +MLP_/#^P0"1`F$$,081!^$)L0N1#7$/41$Q$Q$4\1;1&,$:H1R1'H$@<2)A)% +M$F02A!*C$L,2XQ,#$R,30Q-C$X,3I!/%$^44!A0G%$D4:A2+%*T4SA3P%1(5 +M-!56%7@5FQ6]%>`6`Q8F%DD6;!:/%K(6UA;Z%QT701=E%XD7KA?2%_<8&QA` +M&&48BABO&-48^AD@&449:QF1&;<9W1H$&BH:41IW&IX:Q1KL&Q0;.QMC&XH; +MLAO:'`(<*AQ2''LP>%AY`'FH>E!Z^'ND?$Q\^ +M'VD?E!^_'^H@%2!!(&P@F"#$(/`A'"%((74AH2'.(?LB)R)5(H(BKR+=(PHC +M."-F(Y0CPB/P)!\D321\)*LDVB4))3@E:"67)<`^(#Y@/J`^X#\A/V$_HC_B0"-` +M9$"F0.=!*4%J0:Q![D(P0G)"M4+W0SI#?4/`1`-$1T2*1,Y%$D5519I%WD8B +M1F=&JT;P1S5'>T?`2`5(2TB12-=)'4EC2:E)\$HW2GU*Q$L,2U-+FDOB3"I, +M%W)7AI>;%Z]7P]?85^S8`5@5V"J +M8/QA3V&B8?5B26*<8O!C0V.78^MD0&249.EE/6629>=F/6:29NAG/6>39^EH +M/VB6:.QI0VF::?%J2&J?:O=K3VNG:_]L5VRO;0AM8&VY;A)N:V[$;QYO>&_1 +M<"MPAG#@<3IQE7'P,QY*GF)>>=Z1GJE>P1[8WO"?"%\@7SA?4%]H7X!?F)^PG\C?X1_Y8!' +M@*B!"H%K@%JX8.AG*&UX<[AY^(!(AIB,Z) +M,XF9B?Z*9(K*BS"+EHO\C&.,RHTQC9B-_XYFCLZ/-H^>D`:0;I#6D3^1J)(1 +MDGJ2XY--D[:4()2*E/257Y7)EC26GY<*EW67X)A,F+B9))F0F?R::)K5FT*; +MKYP0)ZNGQV?BY_ZH&F@V*%'H;:B)J*6HP:C=J/FI%:DQZ4X +MI:FF&J:+IOVG;J?@J%*HQ*DWJ:FJ'*J/JP*K=:OIK%RLT*U$K;BN+:ZAKQ:O +MB[``L'6PZK%@L=:R2[+"LSBSKK0EM)RU$[6*M@&V>;;PMVBWX+A9N-&Y2KG" +MNCNZM;LNNZ>\(;R;O16]C[X*OH2^_[]ZO_7`<,#LP6?!X\)?PMO#6,/4Q%'$ +MSL5+QHM\IWZ_@-N"]X43AS.)3XMOC8^/KY'/D_.6$Y@WFENV<[BCNM.]`[\SP6/#E\7+Q__*,\QGS +MI_0T],+U4/7>]FWV^_>*^!GXJ/DX^P``3,T``)F:```F9@``#UP``%`/``!4.P`",S,``C,S``(S +M,P``````````1``#]D?__^Z/___VC +M```#VP``P'EM;6]D````````$*P``$&U0C7J#A(6& +MAXB)BI*3E)66EYB9FJ*CI*6FIZBIJK*SM+6VM[BYNL+#Q,7&Q\C)RM+3U-76 +MU]C9VN'BX^3EYN?HZ>KQ\O/T]?;W^/GZ_\0`'P$``P$!`0$!`0$!`0`````` +M``$"`P0%!@<("0H+_\0`M1$``@$"!`0#!`<%!`0``0)W``$"`Q$$!2$Q!A)! +M40=A<1,B,H$(%$*1H;'!"2,S4O`58G+1"A8D-.$E\1<8&1HF)R@I*C4V-S@Y +M.D-$149'2$E*4U155E=865IC9&5F9VAI:G-T=79W>'EZ@H.$A8:'B(F*DI.4 +ME9:7F)F:HJ.DI::GJ*FJLK.TM;:WN+FZPL/$Q<;'R,G*TM/4U=;7V-G:XN/D +MY>;GZ.GJ\O/T]?;W^/GZ_]L`0P`"`@("`@(#`@(#!`,#`P0%!`0$!`4'!04% +M!04'"`<'!P<'!P@("`@("`@("@H*"@H*"PL+"PL-#0T-#0T-#0T-_]L`0P$" +M`@(#`P,&`P,�D'"0T-#0T-#0T-#0T-#0T-#0T-#0T-#0T-#0T-#0T-#0T- +M#0T-#0T-#0T-#0T-#0T-#0T-_]T`!``2_]H`#`,!``(1`Q$`/P#SNBBBO]1# +MX\****`"BBB@`HHHH`****`"BBB@`HHHH`****`"BBB@`HHHH`****`"BBB@ +M`HHHH`****`"BBB@`HHHH`****`"BBB@#__0\[HHHK_40^/"BBB@`HHHH`** +M**`"BBB@`HHHH`****`"BBB@`K[F^"W[']UXS\*7/B3Q[/<:1_:-L?[(@0#S +MD+=]D^)'Q*M/W?RS:7I4Z_>[K/<*>W=(S +MU^\W&`?T%O%%OY-Q#\T4JY,-Q"20LL3$#?EGTO29E_%)[A3^:1GV+=A4O[,7[,'D_9/B1\2K3]Y\LVE +MZ5.OW>ZSW"GOW2,]/O-S@#ZY^+OQ>\,_!_PR^MZX_G7K%5/\T^)?B;BMA,(HK +MVU;8[G5?$VC:-J6EZ-?7"K?ZS,\%C;+S+,8D,DC!?[D:*6=CP.!U(!R_B'XE +M7P=X$U_Q06"MIFG7-Q'GO*D9\M?^!/@?C7PK^RWK7B;XO?&K7_B?XNF^T2:7 +MIWDP(N1#:M=OMCCB4D[46-)1CJ22Q)))/L?[:7B?^Q/@^=&C?$NO:A;VI4<' +MR82;AS]-T:*?]ZOR&KP&L'Q1@^'9RYZC=/VMMDY/FDEY*%M7N[O1:+N6)YJ, +MJJVUL>3_`+,/[3YE-K\./B5>$R$K#I>JSMG=GA8+ASW[1R'K]UN<$_7WQ;^$ +MGAGXO^&7T'7D\JYBW/8WZ*#-:3$?>7IN1L`.A.&'H0K#\)J_1K]F']I[S/LG +MPV^)-W\_RPZ5JL[?>[+;W#'OVCD/7[K$X/FE&. +MZ?6<%_Z5':U]+71Q83%J2]C6/A[XB?#OQ-\,?$UQX7\46_E7$7S12KDPW,)) +M"RQ-@;D;'U!R"`00.&K]V?BW\)/#/Q?\,OH.O)Y5S%N>POT4&:TF(^\O3&?B9AN)L-["O:&*@O>CTDOYH^7=;Q?E9G+B\(Z3NMCAJ***_53B"BBB +M@`HHHH`****`"BBB@`HHHH`****`/__2\[HHHK_40^/"BBB@`HHHH`****`" +MBBB@`HHHH`*_1_\`9B_9@^S?9/B1\2K3]]\LVEZ5.O\`J^ZSW"G^+ND9^[]Y +MN<`/_9B_9@^Q_9/B1\2;3_2/EGTO2IE_U7=9[A3_`!]TC/W?O-\V`OUC\7_C +M!X9^#WAIM:UMO/O9PR:?IZ,!+=2@?CMC7(+N1A1ZL54_S/XE^)F)S'$_ZK\+ +MWG.;Y92CN^\8OM_-+:U];7;]?"8117MJPOQ>^+_AGX/^&FUO6W$]Y.&2PT]& +M`FNI0.@Z[8UR"[D84>K%5/XP_$#X@>)OB7XFN?%/BFY\^YG^6.-ZG.V.-VK6GBIKWI=(K^6/EW>\GY62Y<7BW6=EL?K%^Q'X +M8_LGX5W?B*5,2Z[J4KHW]ZWM0(5'X2"7\Z\(_;L\3_;?&?A_PG$^4TNPDNY` +M#P);Q]N#[A(5(]F]S7W_`/"?PQ_PAOPU\->&F3RY;+38%G7IBX=0\WYR,U?C +MQ^T#XG_X2[XQ^*M65]\27[V<)[&*R`MU(]F\O=^-?E'AK_PN^(&-SIZQASN+ +M]7R0_P#)+_<=N+_=X:-/N>.4445_59XI^CG[,'[3OF_9/AM\2+O]Y\L.E:I. +MWWNRV\['OVC<]?NMS@GZ]^+?PD\,_%_PR^@Z\GE7,6Y["_109K28C[R]-R-@ +M!T)PP]"%8?A-7Z.?LP_M/>=]D^&WQ)N_WGRPZ5JL[?>[+;W#'^+M'(>OW6YP +M3_-'B9X9XG`8G_6CAB\)P?-*,=T^LX+M_-':U]+71Z^$Q:DO8UCX<^(GP[\3 +M?#'Q-<>%_%%OY5Q%\T4JY,-S"20LL38&Y&Q]0<@@$$#AJ_=GXM_"3PS\7_#+ +MZ#KR>5PKVABH+WH])+^:/EW6\ +M7Y69RXO".D[K8X:BBBOU4X@HHHH`****`"BBB@`HHHH`****`/_3\[HHHK_4 +M0^/"BBB@`HHHH`****`"BBCKP*`"OTF_9B_9@_L_[)\2/B3:?Z5\LVEZ7,O^ +MI[K/<*?^6G=$/W/O-\V`K_V8OV8/[,^R?$?XDVG^F?+-I>ES+_J.ZSSJ?^6G +M=$/W.K?-@+]3_&+XQ>&O@[X:;6-887%_)7B7B\8OM_-+:U];7;]?"8107MJPOQA^,/AKX. +M^&FUG66%Q?7`9-/T]&`ENI0/QVQKD%W(PHXY8@'\8O'WC[Q+\2O$MSXI\4W) +MGNISM1%R(H(@3MBB7)VHN>!U)R22Q)*>/?'OB7XD^);GQ3XIN3<7=P<(@R(H +M(@3MBB7)VHN>!U)R22Q)/&5^C>&GAIAN&<-[:M:>*FO>ET2_ECY=WO)^5DN3 +M%XMUG9;!7HWPA\,?\)C\3_#/AQD\R*[U*#SU];>)O,F_\AJU>&/[ +M5^*%]XCE3,6A:;(4;'W;B[81)^I&)^FOC?Q%'X1\&ZWXHD(QI6GW-V`?XGBC9E7ZLP`'N:_G_EEDFD>:9B +M[R,69F.26)R23ZDU^OG[97B;^PO@S<:9&^V;7;VVL0`?F\M";AS],1;3_O8[ +MU^0%?DGT>,H]CD^(S"2UJSLO2"_SE+[CNS2=ZBCV"BBBOZ#/+"BBB@#]'?V8 +M/VGO/^R?#;XD7?[WY8=*U2=OO]EMYV/\7:-SU^ZW."?KSXM_"3PS\7_#+Z#K +MR>5OA,6I+V-8^&OB)\._$WPP\37'A?Q3;^5/%\T4JY,-S"2=LL38&Y&Q] +M0<@@$$#AJ_=KXM?"7PS\7O#+Z#KR>5<1;GL;Y%!FM)B/O+_>1L`.A.&'H0"/ +MQ?\`B+\._$WPP\37'A?Q1;^5/%\T,RY,-S"20LL3$#,DTUY/1C3L[H_H3\. +MZ_IGBG0K#Q'HLHGL=2MX[F!QW209`([,.A'4$$&OQI_::M/&=E\8=:A\:W3W +MLK.)+"4C;&=/8OH`P' +M+5_(_!\8\#\SJ^[&;6JC)WA*_1-^[+I>_\I[E?_:,/SQW1^1M%%%? +MU\>$%?JM^PYX8_LSX;:GXFE3;+K>I%4;'WH+-0B_E(THK\J:_=[X,>&/^$.^ +M%7A?P\R>7+;Z=#).N,8GN!YTP_[^.U?A'T@S>]?!->W? +MM'>)_P#A*_C3XHU!'WPVUX=/AP(U^A^'>4_V;PW@\(U9 +M\BD_67O/\78Y<5/GJRD%%%%?:'.%%%%`!5BTM+J_NH;&RB>>XN)%BBBC4N\D +MCG"JJCDL2<`#J:KU^G/[)/[/O]@VMO\`%/QE;XU*ZCW:1:2KS;0R#_CX<'I+ +M(I^0?PH<_>;Y?D.-N,<)PWELL?B=9;0CUE+HO3JWT7G9/?#T)59\J/J+X,Z# +MXS\-?#C1]'\?7YU#6(8?WK$AFA0_:G>SZCJ$SW-U=2/---*Q9Y)'. +MYF8GDDDY)K\"\'>"\1FN9RXMS"/)#FDX**Y5*3;NTE]B.J2ZO1Z)I^GC\0H0 +M]A$JT445_5AXH4444`%%%%`!1110`4444`?_U?.Z***_U$/CPHHHH`****`" +MBBB@`HHHH`VO#FOZIX5UZP\2:+*8+[3;B.Y@?L'C.0".ZGHPZ$$@U^[?P]\: +MZ3\2O!6F>+M,"FWU*`&6$G<8I1\LL+>I1P5]QST(K\"J^WOV+_BO_P`(WXIF +M^&^KS;=/U]_-LBQPL6H*N-H[#ST`7W=4`ZFOQ+QOX,_M7*/[2PT?WV'N_-P^ +MTOE\2]';<]#+\1R3Y'LSQK]HOX5M\*OB/=Z=9Q%-&U+-]IC?PK#(?FASZPOE +M<==NTGK7@U?M1^TK\*1\4_AS$W&7^L&21=:5Z]*T9]W_++_MY;_WDS/&T/95--F=U\,/#/_"9 +M?$/P[X89-\>H:C;Q3#K^XWAIC^$88U^Z'BS7H/"OA;5_$MQCRM*L;B\8'H1! +M&SX_'&!7Y;_L3^&/[8^+,VO2)F+0=.FF5O2>YQ`@_&-Y#^%?8W[8/B?_`(1[ +MX*W]E&^R;7+JVTY,==I;SI/P,<3*?]ZOR3Q>;SKC+`9#'6*Y4_)SE>7_`)(D +MSNP/[O#RJ?UH?CYW\.Z:ROJ5TO!;/*V\1_P">DF.3_`N6/.T-YFSN-O(#BOU5)`!).`.235+3--L-&T^VTG2K>.UL +M[.)(8((EVI'&@PJJ!T``KQ/]I;QW_P`(#\(=9OH)/+OM33^R[/!PWFW0*LRG +ML4B#N/=17\*<1<0YAQOQ#3ALIR4*<>D4W^?63_1)+Z.E2CAZ3_$_*7XW^/&^ +M(_Q/UWQ,DADLVN#;6/.5%I;_`+N(KZ;P-Y']YC7D]%%?WCEN`HX'"4\'AU:$ +M(J*]$K(^;G)RDY/J%%%%=I(4444`%%%%`!1110`4444`?__6\[HHHK_40^/" +MBBB@`HHHH`****`"BBB@`JQ:75S8W4-]9RM#<6\BRQ2H=K)(A#*RD="",@U7 +MHI2BFK/8#]T?@C\3;7XK_#S3O$ZE1?H/LNI1+_RSO(@-_'97!$BCLK`=0:_- +MS]K;X4#X?_$!O$6E0[-&\3-)=1A1\D-V#F>+C@`DB11QPQ`X6JW[)_Q7_P"% +M=_$./1=4FV:)XD,=G<;CA(;G.+>;T`#,48\#:V3]T5^F/QI^&MK\5OA[J/A6 +M0*MX5^TZ=,W_`"RO(@3&<]@V2C'^ZQ[U_(\E+P\XVNM,'7^Y0D_SIR^?+_B/ +M<_WK#_WE_7XGSI^POX8_L_P#K?BF5-LFL:B($..L%DG!!_ZZ2R#\*\U_;Q\3 +M^=K7ACP=$_%K;3ZE,H[FX?RHL^ZB)_\`OJOM?X)>$9O`OPI\->&KN(P75O9+ +M+=1M]Y+FY)FE5O=7T&V>\U"_E6&WACZL[?H`!R2<``$D@#-15JPIP=2H[12NV]$D +MMVQI7T1U7PQ^&^O_`!4\76OA/0$PTI\RYN64F.UMU(WROCL,X`R-S$*.37[9 +M^"O!OA?X6>#K?P[HJI::;IL3233RD*78#=+/,YP-S8RQ.``,#"@`<;\#?@WI +M/P<\(II4.RXU>\VS:I>J.99@.$0GGRH\D(.,\L0"QKYK^._Q5N_BCX\T[]GG +MP!WT=KK=]`BRJ-Z`\[&7.#D#\UOVX/'?]L>-M-\"6DF;?0;?S[E0>/M= +MV`P!'?9"$(/^V:_2Z[N='\'>&IKN0+::7HEBSD+]V*VM8\X'LJ+Q7X)^+_$M +M]XR\4ZKXJU+_`(^-5NYKIUSD)YC$A`?[J#"CV`I^`_#U+&9[7S>,;4J*:A?^ +M:=TM>K4;W\VF+,JKC34.K._[U!R>[J_;%?C!7T'^S'\0+GP%\6](+3>7I^M2K +MI=\A/R%+A@L3'L#'+M;=V7<.A-?F'BUPC'/.44UVBDVOO;?W'5FK=XKH%%%%?TJ>2.1'D=8XU +M+,Q"JJC))/0`=R:_7+]E[X`)\,]&7Q=XH@!\4:I$/D89^P6[X/E#_IJW!D/; +M[@X#%O'OV1?V?=QMOBUXTMN!B30[25>I[7;J?_(.?]_^X:^G_C]\;-.^#GA0 +MW$6RXU_40\>F6C03_>;"C&21_,/BIQMBL[Q\>#^'O>`=,?P%X1N<>(]1B_P!)GB/S:?;. +M.H(^[-(/N=U7Y^"4)\7_`&&?`AU#Q%K/Q$O8]T6F1?V?9LPR#2( +M!3[2U\,ZMJVI:]J=UK.L7$EW?7LKSW$\IR\DCG+$_C^`[5^VWP`\"?\`"N_A +M1H>@SQ^7?30_;KX$8;[3=?.RM[Q@K']$JN-LLPO!'!?]D85WKXEJ,Y=96UF_ +M\*7NI=%+NVQ8>;Q&(YWLCR3]L_QW_P`(S\,(_"]K)MO/$]P("`<,+2WQ),1] +M6\M#ZAS7Y)U].?M:^._^$S^+U_8VTF^Q\.H-+AP?E,L9+7#8]?-+(?4(*^8Z +M_4/"/AS^R.&J$)JTZG[R7K+9?*/*O6YQXZKSUGY:!1117Z8<@4444`%%%%`! +M1110`4444`%%%%`'_]#SNBBBO]1#X\****`"BBB@`HHHH`****`"BBB@`I\< +MDD4BRQ,4="&5E."".00>Q%,HH:`_?#X8>+T\>_#[0/%RD%]2L8I)]O1;A1LG +M4?[LJL/PK\;_`(]^#/\`A!/BWXCT*)-EJUVUY:`#"_9[L>N/_`&[O!FV3PY\0+>/A +M@^DW;^XW36_YCSOR%?REX?O_`%9\0,5D4M*=7F4?_2Z?_DMUZL]K%?OL,JG5 +M?TS\[:^M/V7_`(`2?$[6AXK\30$>%M+E&Y&&/M]PF"(1_P!,UX,I[_='))7Y +M+K]LOV8`!\"/"0`Q_H\YX][F:OU3QEXIQF29!SX%VG5DH>ED^E[ +M[V.+`48U*OO=#N_B+\0/#GPJ\'W/BC76$=M:J(K:VCPKW$Q'[N"(>K8^BJ"Q +MX!K\2/B%X^\0?$OQ5>>+?$DWF7-RV(XU)\JWA4G9#&#T1`?J3ECDDD^\?MB^ +M+M=UGXQ:AX9O;@MIF@1VT=E;CA$-Q;0SRN1W=F?!;^ZJCM7RC7G^#7`>'RC+ +M(9M5M*O7BI7_`)822:BO-Z.3[Z;*[O'XESFX+9'M?[/7@3_A8?Q9T/1IH_,L +M;67^T+X$97[-:D.5;VD?;'_P.OV&^)WC.#X>^`=<\83E=VFVCO"K='N'^2%# +M_O2LH_&ODK]AKP)_9WAC5_B#>1XFU>86-FQ'/V:V.9&4^CRG:?>*LK]NKQW] +MGT[0_AS9R8>[J#@^5'F.!3ZAG\QOJ@K\WXU;XM\0*&20UHT6HR[:>]4] +M']CU2.K#_N,,ZG5_TC\WKFXGO+B6[NI&EFG=I)'8Y9GY).34-%%?U@D +MDK(\4****8!1110`4444`%%%%`!1110`4444`?_1\[HHHK_40^/"BBB@`HHH +MH`****`"BBB@`HHHH`****`/I']E#QE_PB'QGTF*9]EKKJOI,_/!-Q@P_CYZ +MQCZ$U^FG[0?@S_A.OA#XBT:*/S+J&V-]:`#+>?9_O0J^[A2G_`J_$.SN[G3[ +MR"_LY#%<6TB312+U22,AE8>X(S7[\>!_$]MXU\&Z-XKML>7JUC#107 +M3ZHV5/N*_ESQTP57+,YP/$N%6J:3_P`4'S1OZIM>D3V,NDITY4G_`%<_G^K] +ML_V8O^2$>$O^O:?_`-*9:_)GXR>#?^$`^)WB+PLB>7;VMZ[VHQQ]EGQ+"!ZX +MC=0?<&OUF_9B_P"2$>$O^O:?_P!*9:]GQZQM+&<+X/%T'>$ZD9+T=.;7X,C+ +M8N-:47T7ZGYJ_M8?\E_\5?73_P#TAMZ\#T[3[S5M0M=*T^,S75[-';P1KU>6 +M5@J*/F_5^SC9?-V7S.2=-SQ#@NK?YGZH +M>!/"EGX$\&:/X2L]OE:39Q0,XX#R*,R2'W=RS'W-?BO\;_'1^(WQ0U[Q/&^^ +MTDN#;V7.1]DM_P!W$1Z;U7>1ZL:_5O\`:6\=_P#"`_"'6;Z"3R[[4T_LNSP< +M-YMT"K,I[%(@[CW45^)M?EG@!DM2M+%\1XK6DQ+Z6M +M[F1?_(HE_,5^4]?4_P"Q]XS_`.$6^,-IID\FRT\16\FG/D_*)?\`6PGZETV# +M_?K\U\7,B_M3A?$0BKSIKVD?6&K^^/,OF=>!J>AZQ^W9X-^S:WX?\>VT +M>$O8'TVZ8#`$L!,D)/J71W'T2OK3]F+_`)(1X2_Z]I__`$IEIO[3/@S_`(37 +MX-:]:11^9=Z;&-5M>,D/9Y=\#N6A\Q1[M3OV8O\`DA'A+_KVG_\`2F6OYGS? +M/OK_`(=X7#3?OT*_)\N2O"GRXJ3[H_-7]K#_DO_`(J^NG_^D-O7 +MWM^Q[X$_X1+X30ZW=1[+[Q-,;]R1AA;+\ENOT*@R#_KI7QQ\<#_=1>*^O\3,_E#A')\BH:SJTJ4I);V4(J*^._P"V/&VF^!+23-OH%OY]R`>#=W8#`$?[$(0C_?-?#U='XO\`$M]XQ\4Z +MKXJU(_Z1JMW-=.,Y">8Q(0?[*#"CV`KG*_HW@[((Y+DN'RU;PBK^K[2HYA1117TQB%%%%`!1110`4444`%%%%`!1110`4444`?_T_.Z***_ +MU$/CPHHHH`****`"BBB@`HHHH`****`"BBB@`K1TC5+S0]6LM:TY_+N]/N(K +MJ!_[LL+AT/X,!6=14SA&<7":NGN"9_0;X=UK3_%_AC3M?M562SUBRAN51L,/ +M+N(PVUOH#@CUXKG?A;X3;P+X'L?"1SLTR:]BA)Y+0&ZF:%C[M&5)^M>!?L7> +M,_\`A(?A2_ARXDW7/AN\>W`)RWV:XS-$3[;C(H]DKZ^K_.?BC`U\FQ^+R-OW +M(U+^O+S8=*BT^PLV(X-S< +M6%LTK*?5(@%/M+6;^VAX[_X1GX8Q^%K63;>>)[@0$`X86EOMDF(^K>6A]0QK +MZUM=/M+*:[GMHPDE],+B=AU>01I$&/OLC5?H*_'K]K3QW_PF?Q>O[*VDWV/A +MU!I<(!X,L1)N&QZ^:63/<(*_2/#?#U.)^*L+6KK]UA:=/3_KU&,8KYS]ZWJ< +MF+:HT6ENV_Q/F2BBBO[2/`"BBB@`HHHH`****`"BBB@`HHHH`****`"BBB@# +M_]3SNBBBO]1#X\****`"BBB@`HHHH`****`"BBB@`HHHH`****`/KS]B_P`9 +M_P#"._%=O#MQ)MMO$EI);`$X7[3;YFB)]]HD0>[U^N%?SW^&=>O/"WB+3/$N +MGG%SI=W!>1#AV.5^)_C.#X>^`-<\83%=VG +M6CO`K='N'^2!#_O2LH/L:_!6XN)[NXENKEVEFF=I)'8Y9GJ`U^;5?I?@)PY]1R*68U%[ +M]>5_^W(W4?O?,_1HY,RJ\U3D70****_=#S@HHHH`****`"BBB@`HHHH`**** +M`"BBB@`HHHH`_]7SNBBBO]1#X\****`"BBB@`HHHH`****`"BBB@`HHHH`** +M**`"OV#_`&/_`!H/$_P=MM-N9,W/ARXET^3<>?)_UL+?[H1]@_W*_'RO9/A= +M\6M0^&^@>--'L]^?$NDBSA9./+N0X029[;8)9B".=VWZC\X\4>$:G$62_5*' +M\2,XRC]_++Y#KJE4YGL4/C9XZ/Q&^)^O>*(Y"]I+#PZM"$5%>B5D