From 75f390200fd8835c35e061bda4bb0a2894318c4b Mon Sep 17 00:00:00 2001 From: Christian Schmidt Date: Sun, 13 Aug 2023 22:43:29 +0200 Subject: [PATCH] Support animated PNGs --- Gemfile.lock | 2 +- app/models/media_attachment.rb | 20 +++- config/application.rb | 2 +- lib/paperclip/blurhash_transcoder.rb | 2 +- lib/paperclip/gif_transcoder.rb | 126 ----------------------- lib/paperclip/gifv_transcoder.rb | 20 ++++ spec/fixtures/files/600x400-animated.gif | Bin 0 -> 11085 bytes spec/fixtures/files/600x400-animated.png | Bin 0 -> 35766 bytes spec/fixtures/files/600x400.gif | Bin 0 -> 5848 bytes spec/fixtures/files/attachment.gif | Bin 30184 -> 0 bytes spec/models/media_attachment_spec.rb | 106 ++++++++++++++----- spec/requests/api/v1/media_spec.rb | 2 +- 12 files changed, 119 insertions(+), 161 deletions(-) delete mode 100644 lib/paperclip/gif_transcoder.rb create mode 100644 lib/paperclip/gifv_transcoder.rb create mode 100644 spec/fixtures/files/600x400-animated.gif create mode 100644 spec/fixtures/files/600x400-animated.png create mode 100644 spec/fixtures/files/600x400.gif delete mode 100644 spec/fixtures/files/attachment.gif diff --git a/Gemfile.lock b/Gemfile.lock index 9b78ca733e..62593e7050 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -301,7 +301,7 @@ GEM faraday_middleware (1.2.0) faraday (~> 1.0) fast_blank (1.0.1) - fastimage (2.2.7) + fastimage (2.3.0) ffi (1.15.5) ffi-compiler (1.0.1) ffi (>= 1.0.0) diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb index 1f40e5725e..bb5a61da34 100644 --- a/app/models/media_attachment.rb +++ b/app/models/media_attachment.rb @@ -58,6 +58,7 @@ class MediaAttachment < ApplicationRecord ).freeze IMAGE_MIME_TYPES = %w(image/jpeg image/png image/gif image/heic image/heif image/webp image/avif).freeze + IMAGE_ANIMATED_MIME_TYPES = %w(image/png image/gif).freeze IMAGE_CONVERTIBLE_MIME_TYPES = %w(image/heic image/heif image/avif).freeze VIDEO_MIME_TYPES = %w(video/webm video/mp4 video/quicktime video/ogg).freeze VIDEO_CONVERTIBLE_MIME_TYPES = %w(video/webm video/quicktime).freeze @@ -102,7 +103,7 @@ class MediaAttachment < ApplicationRecord 'preset' => 'veryfast', 'movflags' => 'faststart', # Move metadata to start of file so playback can begin before download finishes 'pix_fmt' => 'yuv420p', # Ensure color space for cross-browser compatibility - 'vf' => 'crop=floor(iw/2)*2:floor(ih/2)*2', # h264 requires width and height to be even. Crop instead of scale to avoid blurring + 'filter_complex' => 'drawbox=t=fill:c=white[bg];[bg][0]overlay,crop=trunc(iw/2)*2:trunc(ih/2)*2', # Remove transparency. h264 requires width and height to be even; crop instead of scale to avoid blurring 'c:v' => 'h264', 'c:a' => 'aac', 'b:a' => '192k', @@ -291,7 +292,7 @@ class MediaAttachment < ApplicationRecord private def file_styles(attachment) - if attachment.instance.file_content_type == 'image/gif' || VIDEO_CONVERTIBLE_MIME_TYPES.include?(attachment.instance.file_content_type) + if attachment.instance.animated_image? || VIDEO_CONVERTIBLE_MIME_TYPES.include?(attachment.instance.file_content_type) VIDEO_CONVERTED_STYLES elsif IMAGE_CONVERTIBLE_MIME_TYPES.include?(attachment.instance.file_content_type) IMAGE_CONVERTED_STYLES @@ -305,8 +306,8 @@ class MediaAttachment < ApplicationRecord end def file_processors(instance) - if instance.file_content_type == 'image/gif' - [:gif_transcoder, :blurhash_transcoder] + if instance.animated_image? + [:gifv_transcoder, :blurhash_transcoder] elsif VIDEO_MIME_TYPES.include?(instance.file_content_type) [:transcoder, :blurhash_transcoder, :type_corrector] elsif AUDIO_MIME_TYPES.include?(instance.file_content_type) @@ -317,6 +318,17 @@ class MediaAttachment < ApplicationRecord end end + def animated_image? + if processing_complete? + gifv? + elsif IMAGE_ANIMATED_MIME_TYPES.include?(file_content_type) + @animated_image = FastImage.animated?(file.queued_for_write[:original].path) unless defined?(@animated_image) + @animated_image + else + false + end + end + private def set_unknown_type diff --git a/config/application.rb b/config/application.rb index 990a89383e..fb5cd67ce6 100644 --- a/config/application.rb +++ b/config/application.rb @@ -28,7 +28,7 @@ require_relative '../lib/redis/namespace_extensions' require_relative '../lib/paperclip/url_generator_extensions' require_relative '../lib/paperclip/attachment_extensions' require_relative '../lib/paperclip/lazy_thumbnail' -require_relative '../lib/paperclip/gif_transcoder' +require_relative '../lib/paperclip/gifv_transcoder' require_relative '../lib/paperclip/media_type_spoof_detector_extensions' require_relative '../lib/paperclip/transcoder' require_relative '../lib/paperclip/type_corrector' diff --git a/lib/paperclip/blurhash_transcoder.rb b/lib/paperclip/blurhash_transcoder.rb index c22c20c57a..7ca06cfe8e 100644 --- a/lib/paperclip/blurhash_transcoder.rb +++ b/lib/paperclip/blurhash_transcoder.rb @@ -5,7 +5,7 @@ module Paperclip def make return @file unless options[:style] == :small || options[:blurhash] - pixels = convert(':source -depth 8 RGB:-', source: File.expand_path(@file.path)).unpack('C*') + pixels = convert(':source -flatten -depth 8 -compress none RGB:-', source: File.expand_path(@file.path)).unpack('C*') geometry = options.fetch(:file_geometry_parser).from_file(@file) attachment.instance.blurhash = Blurhash.encode(geometry.width, geometry.height, pixels, **(options[:blurhash] || {})) diff --git a/lib/paperclip/gif_transcoder.rb b/lib/paperclip/gif_transcoder.rb deleted file mode 100644 index 32bdb8a863..0000000000 --- a/lib/paperclip/gif_transcoder.rb +++ /dev/null @@ -1,126 +0,0 @@ -# frozen_string_literal: true - -class GifReader - attr_reader :animated - - EXTENSION_LABELS = [0xf9, 0x01, 0xff].freeze - GIF_HEADERS = %w(GIF87a GIF89a).freeze - - class GifReaderException < StandardError; end - - class UnknownImageType < GifReaderException; end - - class CannotParseImage < GifReaderException; end - - def self.animated?(path) - new(path).animated - rescue GifReaderException - false - end - - def initialize(path, max_frames = 2) - @path = path - @nb_frames = 0 - - File.open(path, 'rb') do |s| - raise UnknownImageType unless GIF_HEADERS.include?(s.read(6)) - - # Skip to "packed byte" - s.seek(4, IO::SEEK_CUR) - - # "Packed byte" gives us the size of the GIF color table - packed_byte, = s.read(1).unpack('C') - - # Skip background color and aspect ratio - s.seek(2, IO::SEEK_CUR) - - if packed_byte & 0x80 != 0 - # GIF uses a global color table, skip it - s.seek(3 * (1 << ((packed_byte & 0x07) + 1)), IO::SEEK_CUR) - end - - # Now read data - while @nb_frames < max_frames - separator = s.read(1) - - case separator - when ',' # Image block - @nb_frames += 1 - - # Skip to "packed byte" - s.seek(8, IO::SEEK_CUR) - packed_byte, = s.read(1).unpack('C') - - if packed_byte & 0x80 != 0 - # Image uses a local color table, skip it - s.seek(3 * (1 << ((packed_byte & 0x07) + 1)), IO::SEEK_CUR) - end - - # Skip lzw min code size - raise InvalidValue unless s.read(1).unpack1('C') >= 2 - - # Skip image data sub-blocks - skip_sub_blocks!(s) - when '!' # Extension block - skip_extension_block!(s) - when ';' # Trailer - break - else - raise CannotParseImage - end - end - end - - @animated = @nb_frames > 1 - end - - private - - def skip_extension_block!(file) - if EXTENSION_LABELS.include?(file.read(1).unpack1('C')) - block_size, = file.read(1).unpack('C') - file.seek(block_size, IO::SEEK_CUR) - end - - # Read until extension block end marker - skip_sub_blocks!(file) - end - - # Skip sub-blocks up until block end marker - def skip_sub_blocks!(file) - loop do - size, = file.read(1).unpack('C') - - break if size.zero? - - file.seek(size, IO::SEEK_CUR) - end - end -end - -module Paperclip - # This transcoder is only to be used for the MediaAttachment model - # to convert animated GIFs to videos - - class GifTranscoder < Paperclip::Processor - def make - return File.open(@file.path) unless needs_convert? - - final_file = Paperclip::Transcoder.make(file, options, attachment) - - if options[:style] == :original - attachment.instance.file_file_name = "#{File.basename(attachment.instance.file_file_name, '.*')}.mp4" - attachment.instance.file_content_type = 'video/mp4' - attachment.instance.type = MediaAttachment.types[:gifv] - end - - final_file - end - - private - - def needs_convert? - GifReader.animated?(file.path) - end - end -end diff --git a/lib/paperclip/gifv_transcoder.rb b/lib/paperclip/gifv_transcoder.rb new file mode 100644 index 0000000000..4bb27e3b75 --- /dev/null +++ b/lib/paperclip/gifv_transcoder.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module Paperclip + # This transcoder is only to be used for the MediaAttachment model + # to convert animated GIFs and PNGs to videos + + class GifvTranscoder < Paperclip::Processor + def make + final_file = Paperclip::Transcoder.make(file, options, attachment) + + if options[:style] == :original + attachment.instance.file_file_name = "#{File.basename(attachment.instance.file_file_name, '.*')}.mp4" + attachment.instance.file_content_type = 'video/mp4' + attachment.instance.type = MediaAttachment.types[:gifv] + end + + final_file + end + end +end diff --git a/spec/fixtures/files/600x400-animated.gif b/spec/fixtures/files/600x400-animated.gif new file mode 100644 index 0000000000000000000000000000000000000000..1a773c0af1d1aab72f789db9b662a6980110865a GIT binary patch literal 11085 zcmb{2BS%Vicgp~2l#&J? z{5|;xJml!XyiEavuKjEBK}cvu(&m>8Hi7)02Z#5mX_csOME zxa5TRR74om#8?bO*fgZrj3l^>q<8=_0w6giJ0%_m6+Q!ZU0(9%Ao3R=3OznzJ$@1cL9$mu64x_ zq`Uy6=`p4212YVmbM+ZA4e9d?7z+#mg|C>3UIUBYFvE>lN{!i&#!Tg=fC@9FT2q$F zcffix)`oX%sQ2uR<{V8HoGq5jZPqN`Kd`pju=Rc5?6hU?x8drt;~cQ%9<<{bwrAyx zSr~C(8+Byoj$Isc;&>FdH1UxW6u&&@#53v4#h>83H_r%BnCMLF84V%@rO<3rV^4RXu2dfTpM$E9||wQkd`{^uvumV4ulN7Jrn z^PXSpmjCyi@YbDx_C0Xh9_0IeM8`p7=V5H;PF(kHe9vA&?|xF>VRHYkl!4!=gGZS| z`&q*W*&~NJqrY;;j`GHj^CwT>Q@=`QepgQ)mCYU3%$(HDp4QEs)i3;MS~zN6I&N7$ zX^-T5=Od%m!DvABP^ zba=J=>w4w)?ds9p`tjw)$<^NR_2%jI{>jbOpWB18+rvM1zt8`kTwI@C-ke?C{<*%p zxVgW){d;x)_xkUD(}B$7=JMY{%y>^-N7KZ$M{PK)Tqko2qvKBGwrX+?Fy&h)PiXs^Lio~9y=`e zBlG)W*pwrHn$-mZ3A_e8*4^=X`N<+ygD}mSqTv+LS9{9?HN|7u3c*Co4&y}=`5Fm) zuOezFCyHO@Yh`NHm5vq~)i|sS&TtQ@yzYu%)~+vGfSOH}nhid!9#n}c+fq;I6eYAE_}y6$iZg*&=BlJVtmxjmRaY^51>Jk^=NFRXowI^E9l7tVgZ z^5|@T-axx@wDqR%V6E$(^Wu4%tm^U3l>4f4TkDPg$jnf-|3$0c$=T^X>+pS>|I+c{ zqqTsycedt^I6Uw*6MPA(u!W1{;F(P~c!8I-G5C8V&vsYPSv%ii58k z^48m}M~IO9T#sVwwX=F5z6H1Ne|mmN86u5W!Wtt_2Z@W-u(aEZ2XOBegy^VwuO=As z@%~IAdsXrw$jB2io@`F0QIMh?W?vLw?diRheqG4Oo#DE*T@m=atXcxs}2L~vT$g;Vq0{kQikBt@E6njWn*x1@9G#-_oO=3%$ zcT$+030Sb2kyr#_YulFBVGw({V$*uyT)9JpwnRgTiJi*N7uDaJchQFuNNUhOH4?#C z@)B+hxF!B}9j_cF+Pok-rLa0mt6o z;+~CrIfOGDU)`d=jH`wH;)jNiVTRlt3;WR-9<_~oqYhtj=5!=6Ret0gE)UfF9vEYyX&RsLW8-Is+g%e;y!fLa&UqD= ztv2;0w9wSO08JeTllP&#w#F=k-74$j1U^YMi6QQ_wpZPG3{GD>^On^hdggyEi%&x> zC!HDZ8?Ruv?{>yZ{c-O!F?Omz&00QypwLjcSU*4395MH`(6@{)?uvq@Y;-C}w>IGQ z_7jgX>rk*SQSMCr^HI!z9L*Pp5zV+jT3I*0e&3w-xi#EC9z|Y(Uqx)$;U=Hu>kSU} zvH%Hit=FIFV{OeDIkLq}&ppjT2i`nGH1QPK*1%rH5Nk9y3AKk1m%X|-BUy`BOe*Lj zr-7C)0$;YY?j?W1?ccX|bbNcJfo{m9#?lT6FdYx2F6qA0_fZ=+U7O4$Yb^gYsgc9d zS8eFpGNJ6*u!BLzkV|Br6U<`07cM)_PWqZHi1>9{7gY-dn9>!KvMhF0w(5x7$IFE_ zsvRpkq8h_6#My%|kA<&_3g=}z_Ui-lP^u{UY+Mmcx`O~(Sq1j|yzU@%`r);+GKF}8 zdCc(UNqlYwqkJ;EAeKqXaG>dBun>bN>v2yq}>04_7hojd1XdfP;w`X7S4@g-=RVXpfvW6iy zmqXJe>wT=iuDbllERc#@J(4k)tsIsm!0qLE@0F=MH>kGs7S`@$j!@wQKbkvL z86!*9Gx!asbg#1V!G6#R0)s5 z@U@l|rt~7Sgsmuwn->BZzO-iu@`_@;{UPA>Az|l?eMQ{n2gkgvl?TJS>-l*)^6tm; z2h*F1QShu0cCT;Ek2W&b*V%9P3|E;dt;R8Xa-~U#W6#_3)FHVm(B_nPK#DF`jHDQZ z7f!B<l`ga(C zmZ@8R9BGy`uikb|hcXTJcc#bKdXufT-#lUWe{d;mfqzXRY(EA6ke;vmR0C5Ghvg?b8 zWA$2ml~VaOj`{TrUxlon$tzhY)H8r~-rw}X|Bo#&7*Cl`B=9yRVCxGr$)zF_ifIr} znRJechCrE)7esUk6b37bN-}jMDvRU<5ukj%Qv#*Vf~zU96~sf>z`-0S-!23k9)f8Hv`AI5>SubIsw8FPB8UojKhNZNsrV7a zy*N8Kt%HBUrLpG9Qbh3CQ}-lj57dg)AiMa-r~I2(m6 zJPnrxM`?RO(Wr=@>d^sq(Qm-fKD^QU^P$Z~P$WSNm^X&rF3Q6$rWG7h2al1y4DX`^ z-#!MzbE8hXqTuMLQ*3BWuER=d7@RjO9tE*6g8bQmUJyhd!=rCBVtXxOPlIENb7ObA zVvEtSyV!Bn>~TdJ_i;b$;_~3&M0i}^PRsy7YzJ@br~YW%-RO}1gpr+uZ@lq6it)Qv z@kN30==}Jij(GG&JiIgJCp=+$C+>4(nMi7%7-g4q2u}J9Pr@8XdZrm8 zH4yg~o-8+ztiGG1NtpZyl+3T0+=H25Hy@CykuWa_0b3?3LXwq1DXN+&JxJ&>LqdRY zoRe2vJ{@=GK_T zx{$^WNo>tcM0X`-qZ4Pbld{>9W|fo5Kcz8&GV(Mt-r8rF*{3u@QglmF^afH|+|sET z(;g3`2j4^DHg;ewxf!!v8CmFzF>F{CJ8VoDwqcR_9+GMymHyQ@eWt|0F$J)8CA+@B zxVbC4wZOQuE4yb8m`zKUN2Pmdq)8a39(bqxN=rGC$~=)`GPi)aKw!otFvkH{A38PW zDy0;ZhQFBJ16 zpw7v1ONZ~~y|T*@<;xq>$dj?jFAmJ_$j?vg$VYADCt?<$I14fr3+AqJTQLc~Q50E9 z7g?JW+4vM$@tH0er)BMC)?gN*I17t|3LEkZ8#)Ws_`p+2#R#k7M8yJCAJ}|}z`bv& z^tVBNuZXnZbb(NSbU1(!C=K=YiT&D?_bLq@v{xA7P*Q>k4>ZY*G!cLjNyh*L0m@*$`lD`}U?udd5)2J_g5kUe`y?wk0%ruzz8#`Is;$i%>^ z3f^jBL?z==ir{{AIAKk@QkAz=l_#=Bb}38#hF>A_snQaiiX##YK`t+(>N?gi4^{E+ zml;G>&zDw94OI&6S7u^XAvmjY<7=I2YGHh)8I2y?Yl1$qRsC6wl)+Y5*~?y+=zrPp<cc z#Pt~nfwZND>_}np48!~-;avWv;-SV8L?c2*uzbI%lDG*e(_FUHR39mXL^L&O3pNim zx9$sk*S6`{Z|>r6?iu3iBW@XJ<{uhr8F|Y;M%+4qXqmc?Y?*lrn&YR)%4q#s-P*n1 zI!oL(&)*iP)P{C!%L!`RMYJV%wjJ)b#bSNOo@hPM=01CCdC|;!h4_B+we4>I``@pR zFik1WW!i=G+i?TiJ@eY}JKCMr+sR2fEcBaD+8u8>I(kAoo?CV_4|TlA>!8H#RO09) zRqT|u?0gi}Nm$m&KitW_-mym9#lGJ8LA49Ry6a777bQp6*-#hJde;?kcTz!@x>EP6 z58Z;H-Mj4FfZ^@}csDg>j}BiCmTJ!j`yRHyo~6>Bhkt_hdpOUQ1PBH#FB_Sxs@k-B9h|E=mwOmo*}mYLQ( zIT@5r8mPY2t2G^Jq8maj4>q+7RV~Z64G*;ghc~zeT(pM?5nTPSVe0DPVOix-U#(v1 z5!Ce1bd>s%`$)3&$fBvr!t#i1_sE*8;t$zTajwy=VY#2MQOuChgEFc8+tL1w(UaT9 zXQpEW?qioaBG)Zre?AS}JB{4|$A4mt5+9*{ zVL5+ZFo4F*5TuM4vDyLiw z=UDDkZ0|K=ZufH@IAqqCT&6u?7y=09jDO?|HC!3Cb^bVDCI zt{&7?Z;$1WyR+yvdCZN&4G(y3O?;=27nZHuf5&hd|68N+0n)erx)Mv zZLTg)nOdB`fA?>k+SWv6|7_x8$$w(Dqa|mkXgl&;Fz^ zHnlA@m}`+{9paq?Uyl&Y-Qh41=h}vo%3$KP@pqjkJU); z&W_WO*073ySuwMj$gE~xsAgz0fKD>iFZh{4=LsrOHc!4h)gB zup6|u4fOcry`6QBoBAl;7tbL(+y9(*C-;n&k1H>#qL?=ZswTafFTBpXTiC1T!%+mY zEG`L4_T+PL&Q_D$E9q%8cJPJQmu8gSBeJ&l%1}KKtmUXS8-Cx$^TovqoNGP-+xBly z50DqM+Gg;6iKUe4DJlL#%W*Nu!@6&;n1J=m@`&<}D`CWQ4RsL5inp5;p1+#jQ>Itg z9`xRzn{xy~zgtB+v|KDM&m*VXl0^4^w`07JIO=#zE5Ol7(p6ApL8^Yc+6B@AiuU*z z`-=8{u@?~S^ZX#C3932^ih4ZjI;ATm;NLYOG096EB~<1Sq!A7F>WmQT;N={VSoZDu zB(>sd1%2FihBd^SXiZpcqVtJkNNja}V{FFAw*1fRJ<45Iq)cOyox2Rj9V%m5Jn~s? zRe*DdM@ODCKRThGgH+C8yS(B4*-cJ93I9_jFaiHiPR#|{bcz!ykZ{ZU)Kctu-q6z< zHs{90>zAimYiI0O+E1=cg_>q>yxg@n#N?mTMTQmV>;BB|Yx^wM@6nm{XmFbI=9kfL z16@9>_wc6Id>kCw(k+iFKT8yX-)Kn;s{ei=)9fmr*Vcvqii4w}pY!hG-goNOy)Xc~ z?d*8j(l2S@jcT62A+S(CGG*!a=yyJc5BkLOCJ#7`Nlq;ho=E@4k(BXTxqj5BWO#{{`&;*_lB3{J@UXPoP?lFSS49DXm8 zZjN+%%+r=|X>^M}C>GH;zDv|1hMs;`%{a<=7fZ855DNhOe- zV=Yst-pyZB!-;#p-p#g6*yiCx4FXHzKRYdsVZ7eXVhQAt!jo38^6gLtu%I|a%(XJL# z;CslgwjWGj1d#ClJ&({yyq@3e$wy@A3ux_IMGo@CFo?5<*(MZEou?Ys(Daa4F?5vfGT% zk1cL?Yior0Yhl@E)nf93>PJmPB`*Z)nVQY3xEMB>&FqfMPBx9Q@+W9SlhLSs=B?`pR*~(vA?rNx1?LJNz{s`;)`q-x3eGo zSksSfgUUIsTX0p+&}&D@$zmWx>|jaFe!8z4ch?j|*hp@xz$mnwz_0u>SH4jL3l>tV ze(#VO{FAyyohI6;@A8@hV((-K;EL7;DJ`q%eQOx$vVS2=umBbQi%Vztyht7o!Jy?j z5hLJ4o`XHY@*_SDkm?u7u%t<@CyqyXna?SKBDA{}kB?gD7dMqa%Q^K1Cr2sb_%>^h z>o+vYCFgL8N?}K+$mp}Oj6`w1)>Z?iT+SZosWSaR6He;rr`}*}+R39G$+f=9-Gn-P z{WhUipUi_mdf3@_FZR5jZ)!b5y3^m;rw8<&087t_Ilv<-{MvwpgWN9^uh8jw-IG)0 z7S8k&Zq7&b_>^+;tRLSSKws!%OZ1bh%dfX)=>Le0dd8#si0WHMb!SnHnfQLe{gEz< zp~o=`%^Q+9LSx-|$-G7Ekd18QauyB#aU)79lymzwedD?4#sc!v2V+R(=epVt1H*7< zoKcnT_(x0PAIHRsB;8hAGorUfp`4OJavzqNh8%gG!-EN;SG+o7IQ*eksYcMs43ykP zs--BHQ&o)5?`dDE<-#1bbx(cx7)ad5Id($Lnxc=^z$tub$+2=9EEQ_+Pr5$9>$MEa zgq#|+bSz+>k{7jzCfMa8-Gg0uR+UdDK9bKRefhGEAs_lnwXNSWsvgU;C8;gVzYYbP>&Y$(Di|t;$UYgT;phtYYD1mY~ zL(n_PPhzM5D2gd2RVfa|B%7)ve+e`PGh2Eo27{T>b`&$Hk27>>@_y!##}juI+%gUh?;L01QHTEPDVBp*$X; zAEhynnoyqB7(jm|$7l>-x{_lq;b+wZvR}z@YTg65L2{2Y0U(eZ|1Kb*D0b>Hj1&SU zPxDV=2$4$*e+Gg;coVsKp+Oo@^#MpiYJgxPlQ2k5R0{BzQSONp;3=b=)D^!$3DYY^ zxiP-L)XROnT(g>fh`VN@gp3MGt)fiPK>$bM*Kv`v$>Z)9{#ll^E6a2ZH++f8ua zjU9u7o9CnBq@okNqmyB3?J9$g z5eATg(KckN7-y2$ zeQN)=J;87F^~ycSv|?!f!HIha-TaHv^;vM+3c6yA5|7QQvfdgGO4m!7rIn8UMGtW5-O2f;fv;isU&yM;m&njm(( zBS~Aj^kKD*lvw(-2=i*If* z=ZlYEpM%r@5ks{!V$%dM|EU6;P~nfP7~YE<1ypz}mLH~<|86RGma6z;Trq`J8O~Yh zCt9TUsC-1L{F12r8c_Aiq2it|^Q^S$e6Z^4Uz~ zqADO05?kgTnJ-%X2M~Rcj_fX}HdsWCo*;dwtK9;t#Ak|_uZtSfR&jUh&tjYt|+Y zX*$%<4wm*$*4m%eT2R*MH&^p4Rln9o>Nz6CB9YE-Ya9>_=0gp3HvoCWN8_)^w=$^E zh=zch=*Ps3R!nuVL}~GS0v=Chq33;24}sfvlNN4MSkHSW zE{hflE1ljCz<0J~oc6;M?^=4VXL=iO`xH6)GF1D3pSnD6JH1R@zn1mh`yFuk-@XnU z)($>+6T195JgOh!WD@B_2_=EX==8@4Bqc;qCJh&-L=B_?8#9I}Ghy}F%ap24{Y+89 z>oS7@EgX}t+Dc8SN~S0Z1q6I<2bqq0-$+o_EQ4NH49Qb+KKaa88$Z}KJW#f*6@Nn2 zbNfu-6O|q&PYiPS19IpNlcoj9F(@#?>^^Kj$#NbyvM2!H*B_G4qel7GqN4!qw~RDN zqq`HszoK3q0mpX5$Ig~@mwm@Z6UVNXwQrZlAZKG3nQB;a<3@&kc;%YY0=|U0N(3w8 zIDT9dnd;-A)rf^d|t!ic~8TPr4`AGUZt1Chs{XdG78dxicrb+(#V;C;3*M ziReypDUCk96XN%qVhf&>z7vsMnZh`oQfL)clAGSuA6L^A*2tVzH=EWW72LR;CZe9v zZxtpMG<~HzeGZ#pYMn796?|jHDseXx8qaB6F6iVtJDA65RX%H_&xI`}>U=otI>Jx( zcuvEbi_wokJ815$D0gQr&9}@s!%vK*f$YIhDj`4iuODfMGv`A_c$P@mW6L$ZPBMKW zWvO|)-~k1N#j>#+Q$<4OVXc~4ri;m$T~O$v4Y0c`b5Z1W5hS`e$-l%K*Hurt#0Fbx zf_Aj5EK%Gp#p!l*mQ&TXiuU*|wPh}YC}#m(%l^>z@pR@D4A~V2!OMc=g}b5C zr4@Pf@*UQyu}a(K$C0(A*=^Fn`R2ua-GR}YRVC!g6vq!0z1H&)0O`i+6_gui>W4AA z@E+;f&Whlz?wS^dAa?ZHEB4hdpVml(Xvn_xP_h8dGG}Su35mkcL!xN$Zgh1g7ctp- zhZ`e{d@dIm2R_y!h>UxEVZHE#!O{&ah`AwA!HS9b{{yE=O$VwAhf@Amxipd?>Hhze zOAk2pU%6y9SX(mnzsse6IQ392{fATkt6X}(sfTi@zWg6fJ(Nog|KZf$%6~W&fKANu zfK%u$@V{~ih1}?i{fASH)eq&;15Q1ZOAk2puUu-XeJGa<5D(?j15Q<04gJHZhjPh% ze|4m};rBnBVtw9%I^O6{;D0~b(s;T(p0Az#ytV1i{(Oz&kI@I5`u$KYJ>XPZ%hl=5 z6yp8ZL%DQuv@w+Z;(OcO&E@I-kFoFH|Nh0m<6R5Dp|e{HBzP#7f=DEG)`BV2c+nv= z4>%RdU;{^o0X=sf%B3*gbud@*L%GCT^ng2HR)x-fGfso2WHVkzVs|s)r5fmGqTy@%pGihGB|no*J$HYmn1_M3QmvEix6UXy?Tzf&=FppXL?M$z&lI<+t^WE+206e~(oDe#Pom?wN-NICx(%mAM=iY8{P8i=Fydc?OuLNFHx>s6Ozqj{LF7@*5m(|WX?3bgqO7|;T z&iD2!+wu4hs=DbM50L#lh=b~3iT#6`aW($K+UeJhhjsHdh{O72&;7%OwJ`o)sLf=@ zUyVCOh+jUQR9RpwBs2zvi>8OL?QQ1)^$?{nVc+=ypSm9LWBB!fU8S5;LMbs!LYBM1a9hJ*;b zaTjGy0e?s=t@Sj(-z(sM$Pl)%4g9%j``7i#0(67EM*h#ac$%*}JxvuC!a_98p<$(B`ApEx#X~zMpr>|s~E#S1Q z$6H4z6y|7Xz`KVQ5~I9c-2Y0mvEGWfTJ-#W!`SDIxa`f^o{gWx8b!C=U=<&j1D;!Z zeXF!pk7f)|d#u0CXsd3R$_V?cd9oPVxH|nv&Z{K_cDa#pYVF+U&Q|M%4&E@;+xwNh@_OjBq?NM zU(PceOl6Lt176)Ks{6R#x@o;v>8NdsP=xeE^HlJ|3iq>ttDo0^hc$dTj_;) zX+V>=XNbh5>Unc=5I|8sN8nHUkoro^x_^`6POtr|*VQ7PGN0>Ay^PM4{B7*@l^xC2 zN3L4GO-_4edk}l&D<3{RwfuqpW4Ne*hQ$4kC0cWs9STkFDMQZ7Y*)+(`gU`vsHLip zd9Xdx=$jvGwAc0nFB=vF$I#-QJ`c??0Z&{z_r=;)tlfjIpC4pC-iJT4TRUr95FD{Q zu+u3@jhcLTP_optA|vCVqt)<9f)Wa2$0z)L zaV_%}uBgq@?;BU-4O3jYq2w|s2bi}Nj} zB^A}=ImnE1d32!5vpjRs$|NXZqI@HZNmfFxuvt-Ad`tZE^~-!$?lr{um*2F5R;s5C z=X1!!GL4q$nYiO$o?h$g2l}}j7EIO3uKhJvDiz!CckfE)Il=B<6!QA2`g>KCc?^t= zi)Pe~deW}bE?Y?SJcu9<0cMK!S5z)0st_G`eVm~X$)TvMzEU2l6Rnobb+~t0qG8Bw zw|4*XJtNiRGh^Y#Y~f=<5B*$h4qh@%1>*MoQi66LR*jUEH>j071Krb1SVtNfL9lzY7!r^$DDHWRL2iW%x}tQIg5AG$J~xlXceq1J`I z1&<{sINPCMZG;5;FurE5pKn6*UTbBhv`jqHH*xIg-rqarr|jv!>szO@u{(q}6zn`j z=11ni`HR7ms2IRF>R@mU?>Jnx{n3mp%K6pTyY!Rx9?Q%WJX>y@x&omkR9W=piw9)^ z=?Yo%;zED$w)DB-5pOoHQg8i@9;J59-~l~4CPSIXR#VdufN|Z;y-UWMzkk> zXiEa*UX^lxt3pt!YuodCW69t4$4i9*o{t`K{#u@9*}W6K;b|dJx^x}ycj7kSdw8F+ zc^k&xZx)q5HMh1M$qcxV>8^c8&=GsqJ&t+4AUg--r9PvH1DxYnroFkW$)xJ(0ge7t^844zu+Z)hUKyQB^15*jBZPSg* z?m!dMUvRBcBuQ#7DvSuRaUx@kL>QlO?|PsE4c=pSVud zyw@FO=i?2}T;q*JhWHJ0E*(B&XAwqm?1dJ=hCY3-Yb;fFgJJJ~rTolKQT29CCR)0J zNB&gET6RF8$0j&_Z*W5EBl!WB^AsVBLz2+?w*StK<7c~-#l}vJuj>8uW*za2v4)qy zmapN0;v(Je Tn8Aa4ZsR^0LpIgAVmYj{^(isN?#3df}!HwH$*%$88=;1D%DMDvRjO-FgN4GnhA`wB z9(lG^Qdwa+Z*$hO1BY!hm4-IBCPYD%h+M~xcHPr!mzaMrxPlGF_Tc8ddGDRKMN7Im z1(G31ZeoZGRQCMaR!>#?H$$)m9@ao9Dk$;DCke>~4U^2)7@lt`^}a$tDrzWW)mn5d zJ~s7e{IWvbKp+T<7aHAPT)yp#Qw~XJ9kXz8MKMES4fqr58|#mDlT#+~YH2E99~#IC z>T7%EvJH~az#gACn>wFa0^7r%G zD^IL{dev@15M^-+(D90g$C3*4?h)Ly?s?g~$BzD;ZQ76#j&ASZ7$t8uci<(`Uli~& zmSR!@oKTdIH8G~Do5gC5PRV%U)D;zj8+`GrygZK1Q+N<`AAf0l8GmyJoGDxepT1W0 zeni1_Z_?BWyn2PA%>iO%v<>Sl5Kiq|q0auqd(5NWkr=R8&mlWwvTn?$}-S%?3eki{EEE z>&28V*deeA)Y1g}PBp+?&9i@gI1Oil!~|A-es=x*PppVy2b?pU9-yVxDB)Y!0`!;( z^4&V&WU&Rs9cYW9P$b7Ahl&-x`fC?@O?;;83glI)-lE;X1gAw6lsE?nT2RQET54Ik zVCS$3AZ7GpJ;p1r(fzKq)(9s7zo%;Uh8L=3rWZhkMbF893p!wF9F(X=^b&kYnnjah`{bHMS zF`L#XdI$+k^{Z}w+oy6sy_>+-lKsUv77`wyg2a%J@8OB(v)Ab1sn`2;V}6cySx9kZ;8Pv`OR-un58sNx9h=GbvcNf z_+72J7c0PSh&$eJ*BA*ern-A88co(o}HspA|M(ei; z;u{Rm9T;13(J?syT3&vQ!a8<-n>hjKkJ};(VP*83_RaVRzu1kiv0+U9G@P*_7(u6dRb5SMQarbIvu(xy z3ojqnkSm>*=skv`mTIH9-=hkD_5uT0i!Oz<{B|lIEe5p?(Add5a6E@!WZDvAE-x%r zBa1U$S(u%6;JcmPde_w%pA?>KTXKDjp`6aKs_(EfQlNS#-~Wq2Q$cj-Bd)r2YwM`k zM+Pe?NNc;OpKp7|Z(HyAdkhR#w*FZTZTD!G;^u0>@Y0tL%?21vS3wQ-?@6HHG&n>} zFK(deegxVI*wboh7;^>eo#Fq%$_~?nUAh$gJ=@8TtY$%S2K*g9UaXTaoByO$5@>J4 zdof?7&?M%V=wp4zJ5rzJb$&QGH_?7%kjo$56O^ z7Z_api^_jj#Jxhu{dYC5lv>^7k?LwHsf;Zq)!*r`W@eRm!~b&m)Gl0ozw&<@%My1>rogVO5F*%B z6+=_8+=@~7puIv=3FMOcEwg2J4K++zTSm+l86BD=nmEd7Re`67!X*WQX81Yra6K;&h;b ze-$Tw4MYriUPZcOecDOk4LI|B_!QAHq>H4QA}Hm_^Xd)>W;u5Z`0gg0~=5r}0%{BPxo%Om<^61G{QsraJtom-Q`)k?5zJs&i~lX;{gk}%t%i7v>nTMOA>ZW5q6Kofy`Dw4n(@@8$2Gfi zJbE&6)57e=)-4aS%yBly+yy&Jn+(Ui(9PtNhNDna9^w4El}C&#t69NOnP6VYE%wDs_d`9Vk-D43jWZ)~U2I{=9KwK;No0 zAmEKrMb$i9)z`Z5;jr&>gYVL|WdWWO1DuZCDS-oH(O$Jaugg#Z-sA>fi08vr8XQgP zV#HDO2gdM7Ec(Lh`$rY#ZJlAO0Vs1Jlgze+}@DE>ZP&#H zczC-0&?-}5I^j%fj07bqFHAX}PKf(EPyHkl;W!e%d?@*lR0y7Hof-x#oQWbeYH{Jd zXxf|2RVfL{6kE1!jd!1qf5W193}aUG*kgYWeSs3ZBEsY2`ut2|Fot7gqfO+1+mFG- z$^Bb;!eG|=2KPz?onwcjb9=AARE>d*%)OLX?YU(`W-5W-Z}QJruZ$~1{nd!4WdNq& zQ}-$p@8m5qq%L+{_~vOQRZ#I2Q}iPm*C=Ge9RHvA;hBC9o1xL#EQ9Kjt76VxX)GE> z4l6G?5G#o5#8c7CG6QhNud?_C6#Kj6T4Um1UkR_uEj4!gY3DB=vVP-vUa7wk9$Q$@7eI~WR8v3Kb#G-Q zTEp-EWq{fxIX3*b=g}3o8nT0rn6fLs#&G5A^pI@oP)v%hR{F9*Zp^5X<#Z z+w#8eu@X6b6u(8|HHKhWu5~Hfxxn*@8>Mpcn9Q(`~5ENlyvlhRhDGPnt~iA@JC z+T=cVVt8}L4trFV%qwhNo+4d;i|d{l?ZARFmzCmC>4^M_Fw={L6ldAz$Sm=bKfdys zYb{iUHN>Uynr3b@&JiIJBk-$V@8Ku?N_fUSQ^poKkiWOHPOEZ#Dvg|@dI35?yBGA` z;TCNf`)nJA~>;>2=s`nbYx**{3EQ zRT8F;BcEFzv;>30${8!{kwZ6P@$rFXC6G02GEU5GFi@rf`eZAm__)l+J>X@irA)wK zqVLJfbd`k^3gP>!Hc02WbUT$1=g(DArBy^rb;Mmo?wK#P!-KhUK%>)XZUUHWaeL>FQ?G&lum+wmnAb0A2n4!%!h{BGAZtf zSVkKM@3we9B7(Ao{%ykEjA0?*C&ncxY*!8+J5SNTZDTQ)M^Cm*wJN+c_!hnHExEkh zcg?V%Hlra!^|T(cK|`V0ib}6EX5_$W{D{Pel6M>B7wA7W1!uDKo+l^2@rm}@%7&&# zc6+U`EC+@9ZkBb#XN%2>cUsFl6NkoVrGJxj)RjBc=c_h@#&u#d*J41Ud0_bann@XzLPkMfnT+>H7RxRiJ*0xPC-s`pB;U2xx7SU zjP9%m*u_m(Fy;q~(8jnR7bKhPB*PKQcf1f-vW|g)iOz_J>Dz&>l_?7!+$2SkOX!Y7 z3M3K+Bw_-sq8bF^6m~PPtoTXR5=8a=?r5)&#Dez-rutlqIV=u7=B%coA8HoJ~+*q{#-QkGflwGJy(X-9R>SW`>UB>L27BF=a=Y)Y3A$yDfW;C7ktlODrO zFIq?qLu)rl(&!xh{%D9;%jWcHv{%>$tDg;?yFD^PQA_vp+kGh_XSm;`ZRH%qOcDl6 zU^HWJcX2KxPz&0g8cbtLRO$NA8`&`2cDN>N7$zf`xa=XOq^c^O{TQGX8;7@@7WYmm z#B%DRYv7#~erMXf2nIf?p0Dn(?En(sOJC{9!7bN43z$)BMhZkyCc4=7PQL zbF%JawK@iCnY#G;pI!2c?bV0Zv@&EBo7_k4|2gUIRBGhqF+ab!|EJ^VEg?ocPA(02YE?Gze6t!6E)k<-boUz=KgF+xJUZMVriGzKb# zdSA?gr!o_k&iMVx2fgDqz{7Ug)A{W7;fJr*;5ql%1Y|ojMS|zWMSn@^Jynb&e+P6KMZ}4P;cGs79i#6kT=$Tuu;SqIy{>i(K zC)byj>~==$SV^G2v>0!vPhakQg?721S6A#%PB9D0m)_%oi@wdn4qD9oPsiE5ZS|W? z8(*f2@SVJqJg5vfK|k(pINf1Ax!$;!gdKGhvAcuU&$-=Xl5LUJ^iVv(Ye~1tzWHIb z6+-44C5^0vm0jf~{P?QOl}Osft#hLAzzlK4GsUnlv(SghDbxqmpS(#AM`k_|5eR4> zKkwL1%)}T=oquGLuYhOEZ!Rwk;~^KC}r(I~Q)v*L3_IhlRC%M0tO245hT4o3%KQdE~f+VBUEu`g6+jD&|ur ztu{-3&1X@*ytS#jVmj%^mhQ^HJBkAve_>=~%T@61P|_u;S=74*d#yHt@%7&KsiSMB zRNKxql(bs|e@kv@-MsTka$KpVM&oF1(BkIp_ok-eQGH2QymthcCx<@-!|P7xrVU&N zKLn6_l+~2xa(B@E@vrlIZ}DR<=PX5hRq<#LP2rRAJ8?dk{$0hxmgleCrhs&=oQCA* zWmq+;?p(|=FV_D=&j{KyGri&ts`RlevUhBL#68OrwA*fdJ4pnfs^TM~&hMw8Hzjp? z7Skfnr^+6Z9HqZyz|Z{9qdfiUQWU<(3ieI);q_${Jz8*?mTcdn%goE??}EQ`@~A-k z0yoS*eTQeEpGm&WJ>;4L0(-OLd3ztc(#LDR$0Bh{?~aRv{mYk&6nr9rTZiRaEdgXC z$;e)x(?V3(t0r(nF!0!g3HkM!*Q(Dryfd)r4lAB@PNorN-dT=%dC4Tqb^Tu7hvzcy z7k(Ivw5<2g5=Sfs{eD~QrKU-JHVOl}HXGyXWILd*BRg3kGK{?S^!DwD)uCP+88b&z z$g`iFRg!?l-#*$dpLv1|xzB%iNJeB|`7}o6Hf`?TRY!IE1?qj%aa4d)=0vm*uLiln zgr($+pmnj*pPE!Hox%&Si@N|9mi-Tam4H#FXN7RQ+LOWDutk4HbT& zKH%|UU=>~q?J;13Ict!%zi!|F*v5F$l+}q9ckOpO*Y>Yf`Fjgq%Y3({4}05C^}GI> zHy69KOoRX3@*7)49AWz(y6P*v^8CMu`3&Y<*;(FZg*AN2#Nu~YfpatrnO<<;aX<;W zZ0G&{Ir&^KvX{EMtUX$!|41>^w{*yq{v(y*G505N14x=;o4c~7to!P8N8(7s7J7ih zg^TV(qd$C&Zk_br)T5T?l0whJUVN~eyi*2^d{+*mznfPLlw>s;S@`IyS9U+uDLR(5Cz zF$Fwd(t&AguvUwJI3n#0R=ebMOmX=UeXh%SlWs>dx0MD>#a#Qls(52LF)|JEq;~^S z8rrnosVJ-QtQS(f^p!vME>+&Xt`9;ilkr@uRVR5j3CF-mp~B!;q=`P(*FJcrs*|6wd>eb8Q+TIGj+rY4i z@zfPL%orslX057*7Or$)9IA$7Bo*@~w{J{Ko_!)7C>G-_pJ#51dI@x&iGZKxW7*rg z>HD?a3s-W4>Sx1sO6P?tv>s$QYWrgGp-TS%n$pH&GXDuhBrd5;5`I~NXi8zj;;fQ&CoiUA+*)8DA0}ln*2-C z`UR5>W>xYeU~$_&pbr#s?jQfEjqI3andy+hda2*%M{;`_}SM& z-<%Qfhde`J@ndcg@EhJGYTz)-p*CM*Q~axfpTyzw+AZ`BjLj_P<$(!1z9_rPjo@W6 z+)BEvdO6?inciHZk^S-y9OV!lgxW2Vp5KnTVotsd9}yn^zTKS&>}J|)F?bL^GLs4* zEPM#-gBR`Ygy6Nt12Twq?+t!$>I%@eL8{7-4Ltt#4XM z08Z%tf2ua)03s0p7f2EkF7pp6PyyU0UXu#5|2s}K^FN-D7y-1@R2oTed%%C= zG83kz%kUchVRHvygL{jJdDa4>z%d*G2?=?gqm3gY+lc`JnHEzU4f;p)KTynjutzuz z#ixfTrk7WF(ntV7K;%@uDq7`&fCn(q`+E=}geE`1$mRb*v>u-)dFFo?<)8hJ2TWgJ zcye7f-n+oD0^bNa86YE*sW;K}lOP7Y3fPQW(fNz{qY&H@5AV0lgTv)N@FP#!+=0ho zi~}EN^48cr$-qM-?t#m`-JJ|a(90~se%$cCwd4?p(-qY=cT&JKW6%i#Y1AT1`sRjv z#Ns}BX6gXBfz$BZh%E{NX%mBG+vVe=NDgRB(E(z_4aKorc>P{26yF`F8-)@OF^T%! zKiPn2NdkU5l^#G#$Z-qMOmIM>G^v2Fc2p@5@F(MTsE|A0qi13C$@Xz9mK`@l%Q0^81h%yD}fT|^LGr9Cg`CXcg!Eut1Hibt9e?iL7<_rEeh*j30}GXO_l0}kD7XZ41Jv*!Y@C68lR zG(brEvs5Dq6zqo~Is?Jr@s2;xdE8^K6rfdA?b?4&yGFdkkeq@n=%~^fh&?%^Vsi<} zAvyV8U8TA*plsqE4U9v!|G`xVwY*4f1NH48Kr(yrHJm;!6)@KF;nD+U+H)5=Fbd>u+ZURc(9U7 zHb9tNfi$)fdIgsvq2{@RvvCEr2`6AxK!$8;q&O831}b6+BCfmt9ujnbJ-!E{Rlyox zRlYC)*#b+6z^R{N$&7dYw`ymQ-vY!c3gNgdPddThONN0n;W9ptKPTJ7NJ115*WZTpl$zXm3IbWfU)HJu=^U`- z#heq@@{fv_I1)mB*5-L>268cafxH&mN5jwjxB?E0{Bw%?_mDa?E``Gm)YC-)LL&6- zZ?O@`=Ku~tSi68?mfQeOPt-sq@G1l`7@q;M&JduBefjUGAsr>so3s^HAklZ@+YNpQ zN%f;oJ#_=1$hHdvdjsYg5}V7`DMkcwD3B{gYKkJ`Tt5P1HbOjDc<5;E|Z z^OtE7s1f6abFCQRA%6c3-I&GwJk~;#YTQdf!BOaU_V}9pmp4Wh6 z_8y2`oXtDQ?_G_pQPiM_=KjpV z>6eMW$S|ngQR|A*iRxz5fhj;*Y7y(T>JY>Y2eXyZ6JYo-7QB9aoT5mpm+eaLY=+HC z+0|gxaIc{vxDBL|{ajsnK`M6v&PYOxpH!TXVv8bxgp+eF?dXUO9!-~B`3X!Zq5O;y zxFAG|PucXa0pJlRQo1Mb>)}lDqS^G>9W5I*B0r!;+J$L(Lqb;saW!qqG`3l?r#IdF z$K3y`l19bZsvw>T;0lY%0=w0VUH@bzNbnQ*2&4`pniGNuHX!HGV)9kDjRXa0b6`5E zJfudD7+v?oYa8Qwnqz#meDd```}00K)B;XFd>;C2aVc_k#m+Jm90MlE8hf?;rklNg%*V%uF&6Qi{`(D*=+>y!LAX8eZ85WbYlAk)caXG7LN25 z$?0k|;{mi6Y_NuCuS(#DxqPt^kNY>c@37){E3RdkA-8lDkB^9~npwaI!n(xIRQ{B=+_{LC5mVIz7kzmP ze0wrC`alaaPzT(D(Wr|_DOsc7-$V)!8b7TxiH0PDf4b}$xgJ&gxCkkJ?&V~nl^f|}2 zZ?Co=j{@HyUFA;^_8NpWOh))uNn}-keUX?)=I2CaHifoG+FbK$u(d9=spWRnly+ku z4?g5u`J!+GR5QA??tqOT#|eoX?u(Czi)4xes&>dfx(}^M-56h92U2u6h zL$Hdnj4KKsGA(?Z`fTymhdtrk!p0TS_mv9QX(|?bbcbhv_J~cKeb&-x~{u*}@@~BLxX1^v;CAx}wN;z({vy1WCRUg7UnlAG_YY*|IBg zC8c@_3#G$yVV@mDmg&4SYYNdf4W|XkzH;Il@CyO4L_1EPXuH3bf>ao|j(v<) zg7|(hA^oG3-F58jj&<2o(Es)~$)=Y4%ByQ&bkITLXP-VelbhbNJHw;gX&=d}+`W00 zkhTU6=UBu2+DW)`n^=l%8RWsR{rPQ7O^(=Jt{!y7e5F(&9q>zy=MNQHv}>ejV#dlt zaxp2-cezG0I@P$)>xYCH#ocN1R{?656TY`X1XnKPjgW#Z+yi&A6l!)#Gdnv6=nyN9 zq!&-}mTTW#=|F%E1FUH zbDh_)&0>rdV#`^idxjrM?0q#ezq*K&UZJZ&4sV>EYaHeLKD$TGRzBLk8E~$3>!2s( z{nx9U1NeRAYm&bP_MA$0cH)YhpBjvdX6kCA&GIvYU4`-P{$2+)QZCN<5a|->%60mZ zQp-jLUGX}pj3Vco`N30l15yg5#mPr|iQX~KHk|xnft zmAZ@WoD<(#^g4CC4j5QJzz*l&p5fhzK7|aTyhDYAfa6X|< z*K3e!nGLyu6d}K{1nPV6 zFP^DC1cpa2lJ#GYPB*DVRl*8BN%lOoaVaUVzv%s%x?*4ZjtB%nk(E`A-|YQG=HX0# z7O!r7!*KPI1&#}7j_KCuW~fa(m`IosgO+HO^sYI-tgY~o)Z*mT5P#M?eN+FFR!<<- z>3A{j!4c)*bE^tU&E~-$dy%sPu}lIVxqQT>VU2%N zgz<3Y&w+KVFM%NUUGjB{70p>9vhh}xPxGtTyd0CYV`}eO{2%+gW%bOEQ}S|HZx&j+ zPs9^~Qn*Y;ORS0)O&!TrKwCQpy1DoE50fZSfg*;9M5h)Ju4~qA^=i+LOdi5sR?0ki zy@vIWceH`7gxNMAffupnl1rS>$Y9av#c#WbZ!pJmsa2~UPMf;~LyLOqZ>;o02f6g7 z=E<%@4o&?RTfTS%e2P7}a49XW+eth)m(G0_wz1?>6t{cr921bOwduWv=1z#&36CmM zAyV|dZ-}T}^FK%>eR^`?{0e2VlfRStM{D$mio_&?=y~M+#XQtCbHwt9Z>4Ayb~$Ck zJlVUL7zuW0nO9qTW_T1KxAFK^`W(_Oi!r|&1{y(SfStBNW>B7X!R3}{i_KGC=e=8n zvw5wC;}7P`9=A_OkoXOoby#SlJ+sy$ozjzegxlK*!eRVI_o*%3Po6HOW_dj+B;KFW z+JGHeh%kYJG?S_G(TH;_@=BlQu;?0Ae?&;~^0BR7n%?eIyHOpiB%bjo@6h$Ai&?3~ z)g=97y;O0hxKrb$@Ed*C*6*k5Pem>Y{rvh-^8I5*KTZ8TA?`s4IuE9Kl1P`14EA|a zBdCqwy7>P^Le@jw7i#PDT|#%tFY4k%k!gTZXbdl9QmFYrNZ@${+?CtICXLjtWrro# z@AB^uboI z2VdxMTaZk-k0vmAhpsU+9nfRs}JT*-M)L;`Y=|LNVAV`<&s!qDSPh$kH$ zIlI1ix5h)zq{Jj7)CI?bAkH{oY-?P43Q|_6sFZ1&-CPbh=tzLDwvrf;_+$juVQ((x zNVBQo!UIqfr^mO=w)EdC!%A4m7l8!ze=jF>)fOC4Zy&}eVC_&u5V-)*L1->-a3PNY zF{(1fZ7UFw|9hFyKmjE=_zY&lS`B-*MnJC=z<>>A$)V%x4NC1qWT%BK#NaFqiID}3 zZ=Wp##%L8Hk+qvIGwwxIf<2iv5cKASBMVJP4_>3a9%>c+`iBDxKD|t~Krz?at;whT z<&Vd#`-o<7KtN#T*MaxTl%9;u7$VVnO`&Eak`NNb4zr9;h^w0|Yxm#fN7F$dyP)|{ zv#20#w+Lo?bf&Y|rOIHq1w&ClP$SQfv9O&Zg#Tr^XTD%YTJ%~GK8Wh+-d6pt)&aZ%W9u2j?FSzit zL8+~S{%V8Wlj4M&NjOuKr1hxHH=5da5Xchf;>~pM(mr)oh{y%R8+E9MXQFWgfvkgH zQE-o@Devd{Z@4**qbW3W|K<>Z=E^Yx7(TsqUHG@ddYtCa7GBiS-DLina-xVZu9#6emK)p-Q6ejZ-@|U9I)(uwVt|?*uK^t zu*R)BXNQtb40s@m1Sm{=dpvlwp7ssEnzLUAw*j2Nmo;27Y9w-gKE7xa&NQUETYCap z7iI*nK)y?ZIW<+OD}kG7y-rg<>la2D0?W#8Ruy9vKm;BQdQnwXc8E`GYp@b?d570> zewVMS_tjQINg=RJ>Wc3Ir;{2;w!|BtF>(r2_~=5hfocER>mBhRo=kY;^OJTnCbSiK zGi4k^QN}anQ<>(tTM_6`kRf^tfQyjJ^AR;2QSh{k-$Sn!dKVut!cf;CZTUciX?o)i zE+1!}?Eod^S8-F!#%y+fo8UOCgpxsE{Xo%dOO>$tC$>>IZI6sB*~JvGNT0o{RmX!k zG2@Y=x3b*El6bQPYoW^Tx9&>sWL{1DR-B1CDZoc}Lm)B{ps%-}z&RkOtb;l6nT}cY z-lA{0#zlKLI1oc1w}9Q*orx-0?+==xy}BZ=6Wdi^D2}Ce>rq0enF;up2EL*<8BSXQ zYg^K4py~tH(r7ZSI#!CET&_3I};*%1uf{~rsQ9>VSWulKdp0ADfiJiV8`G(@GOgf-j0)*PZJ=T)46KR}v_MBSM>a zik$eu<6X-=J_ow) zn*m!MdgM%TpRuF68~V1;Z;Rp{dxkd-cpj~nx_wv`px2Quu5*(R@YlSoE~RLyay5@6 ztk5Je`icSvK!^=Yf&_*7cM{gWdzB>=^~7J8g3A}`o@=j+UA@N*6VD2=tM6 z!PoD3wbgfhnM+x}GMb!#rC+8##C1>RD|0Ka|L}D8w^={(syIsw@T1zmdNm8Yu=tcj zXt>XFP|y(5=84+4G$^ZM_8ah|!M9WdcL{hQ9%b#krhE&0J?zjTVwfU1ZKH_Uf5+bi@V zLrJ$=BSHUhkXKYjL>rTyRc8bE7rl`$EttvblV>xP0nL zwN`P+fV+rj#K|+RI5sgkDM-&XYce=}f1+Xil#}J$Rb6ltogVG)I^U|_T}r4<<|ovv z9{z3A&^0yF)wWsOP>-n9^c&y)&Pi>|#&xD^vV0O{bMLxlqd<;ou-rW4WXM8C(PsEZlw=S^2w_<8T4F>#Fh$Y}8K(_>IKf{rbr>RBo5; z3{^wPsii^H1P3JhnSuBtth!f73)%`r&uRryd^jure#3Z7s+5&4`gxBxtQgcGa0-|$ zjEm|*l@=^dwykR&@z_DZ;@^7_T;#S~gDfWnF_Xm!xMreImi6z>s1juQ2AFs!^cgst zx~UcDHgr%=SHW8m2K=ng!Qn8~fM{zQs5N2pls@Cq=6sm~eE>1=(GVlUE%sDpes0%ib7Of~Ewb{YUlbtn zik@8NiX}KhicqHB57bxET)8RBcQ|Hoq2$^J*OZHXCIcKEBdGX^>?RE);Ibtxs~>a} zq#aPqteAv2f2S!3%$k7zq2tn^?gpPj+VFm^D}8jpBwSi<;XV;L2@{wqUX{081E!Mq z9Ys%BT=ar(Lp-2j0+v;9(tGdfYeHOVofz{8_)t=!&Q2Pg0xOV9!wI1hgsKk;o63&y zIcE=()XYA$9=yS(B3x376Ha1Z@YR2Zvq8k304Vz7PcO5Y1Vw7U9vvm=WN?JMQVW!H zL<#=TRTa|a`BOSMfu<@faBN}29caL1tbf1_gDN+G9p$=n()4)377 z@L0x*GSdQohe!zP$Iq1K2zp%NVwP&?b%Z9kp?T|WF;c3vNzB8#NKB;f{e+If+}#v5 zW-%V^@{pq4Df+9E!-F3E4r!pn@ft!)xeZ^e^Zi6o!Jt`L=Oi^|@5u)3{N=i9EBo3L z#fw2ho%ct6m(?H>^A(suV{F|Ns4`tgl!0}iu$A#q?#4~eX^Ex^xh>nCRuvv*8U?q} z$7TH2)#l4SdwU)u2ADw-sITgeKsj2FOzsF=VJy{qWxeuP~oA)hF)(3UMPxiI4#YT*{)6E2e`l!V=e!qXmBoH zE1h8-ojp@>yQtOQe03=g*3~!G+-udfzBM%~NQtYt zAf#@2sgHTm)(E7|G5l*K>mPU7Xpbe!i;S_#f&JW&imBdb0k^d=srHW& z^lX-|2w&lK5K-P>J?PYf?giU;#iuzNlCq|Q+sPp*ldPyZkkeA}9OcyG+` z_~Lg~nsx!-zHGCu>m`i>5+e6^R!Zb+lj_|+RL$iM`{(5T>nwS}PJv8LN0ZryivF)d zkx8F&@_dEIxFKu2`1C&@B18FBe*NQFX_d9dbrLuH3|)Kk9MUuy3@W*4g9j0gxXfCq zl87dP@_OLZ<$-jw|8vxZlDKCFimDE?Xq;%0j}KWb*1Rwta`es)|G*{seVx z*QMI_bHZZp$%S{K9(S78ovD)xK`yh@Lg9UQ$U;kOk$ubPfU$vj^0C%TX}sMiJ0YtD zNX&N0)2@^k)!T1uRi!3*>wr8FZ@K-etemn!1LC;Mw3%+*8qNHCht#N1HqP9-c^xk# z-ig5>w6V6Xwf05UGwf^fd!~zgJFHAyl;ZI(HnR3=qUfv3T!F(AFI8ufRmQqhmIL1Z|F;}I$h6KvAPP*j&*k;NX#D?v&mmpuy!Q{%E?%tJlq@t) zoD*d)CJ^dQ?*3IE{BHhSPS$Nrd=j6j&3oYwR2wc>!y%s?0Io!SpcQOxD}vyKT*FslwXhmt&(MrcvbujuJCpJpK1pJyEbu1LG;r zl@m<4Kda#U;sV5#`L00ZA#SQ(+(ypc<5uI*Wl5H>`}qRfvo3i?YiSefssI$ z#1?(47usp9wL3avk?*>$Sri>_rgEP%_$^DbJir8w#%~CXg{)r6llhk0D-^!=M0s`Q zg*3fB-yuH^+`P<)i!Q$m$aDVfT6%EqJvlKlb!4jP+*mq^ozGgC-BLd}w4cAYeWu|x zgBm@UxfPsQBlEiEV%GC~F9XB4vBI3&3WrfsA6SbnH~Ml=BL67HVmpahrAUkrof<}J z!w!Y_n;%P1r`sw7QBq=reyY@2Z2bNm-g2Jovgc`<#5|jB$`BNycaMzcGTZM`oA!A^ zg7=!MZ!qP9DU$56(W84K@~cvunA$iPe*N06V2^pk;`B8R#YDcL=H}-w>`?*llQ(@;>_C<$7H+2k(|T-V_dF8Q0kUnaE7o7P1%UadJ6 zc_bgfc5+GUi7w{z%*aD4Nt6WW@)%Fe+~Q_Q&cMJFkTOrOjRG4R(x>q*vc(0iCoL__ zUn%@kEr<3sky!vvPHizX#+;G+kDk9a+)*jM zhIK_Ub1|hbkFPG6D%!n}FeG&=X_@K;R8`5G%AOp)lYp_rW;}8g7a1Phj>h}Z2_#Br8&|`~HOk#b zE4li>##L)dR5ttnwD;D3QAS(*@2DUpT`H~8N=m1Mgp@SMkTNJkh?F!+gNjJEAPo-P z4I(v2cMPI*NlV}Tpyz(ieck&X-18gE%#LS2JJ(vD_qM0zx?xzu5*ta75#_T^8xx7q zP)<%epLm^K>gta-vGw^%6fLJ{keRxkvZoGaChN+6YCtTKR5om6Y4JO9`DjfGE)j3? zXjCv++hFv*<#~MJL8*}#$s?@0pL_@S`NgnyQddf-bw&_Y&OL4kn9&2hc(Yqx=_g)` zNh}TxBr7CdV#ZGU*09Nzy4Y}1W!gKU9(+EG8FlJ-hug~bdwEW_`;>GG4E#II94m?3 zUvhfATa0v`*FI~q1amgA3iksZldOuvDbS*;H7vr7>~-k}Zw}RErZO_B%8=h9VGPiN_xgV z5jG=4zS*NmnXD&?AWnKY-F?M|8ea}*@Mj}1Kv8p zV@G}mVb-Twqc=57KxpNXgERdcOPb%vQ?mtEcDJxY-!zlkoaj1K*TmYj($KR%wNx=< zTx7W9m#OAdQ}5M`L>`42G}k&j-U&TC?EQ6GS5k-%V>HC)U0ImcuH1Rq0gme1x=ycNA+Wo{VX} z`ADn#AVZ^fnV7R%tkB4&rfZGGv{v|2B}htu=oK!7E7fovml$O5k8Q|>638vSNrG+L zn=VF&ZQm?Sl&+CX94>4|vW`})+3(kt!D%&~iFf|E!!K@z@?M$95kl_2<)4gR!X%j2 z3Npq-DXxspMmOxHDiPayi^csEE}ef>x`bLE@ReaSZDvPo1dVr8f#)=L+|wF;Sg!;& z)MFj*n`sq#&t*;K6U(dYgb20=O0i>qKYjR1$5_faV6(n1l>WI_Hd(E~q#dz#l z%4qNYY$v~Y;$>+`?Iah$7;x9ieKc4rE#dOWtF~5Rep%>ZD->A*r}kav6V-q6otisy zwe-9o$6hjgo`FOM{JJY@b>SUPz0Mcp)$dv|Cp9~H%*}6te34OO3LMUhzR^ewU%lac zxnuhzU^!4hEC+-9ymT%PSCsI9p_P3!EfQF?>ZL=Nvh+Ba>fM%W);4?EI4d4qt^sCW z4gS@|jMciQ!=$1^@gfP7U=brGTqVh`M+`R|*3sG4kT(s7K*#4W1 zccVm=c&-7KgLBjwM#_&cw=lKcjsTbWGF6K_y8&1Py=#po2g)N}My!8?`G347n4$LT z=0N#)_gDfBbX|xUzfd!6FBOl*W*Rm8}k#1N^{4mqVI&2kQ4#%AXw&@uwmXc8+ zon?>nKHE3zFJZ#Z71Tq5(8C?qZnRtlgofd$Rb%=OC}e|)Re|Vfx8#3N4t8*f-^JTB zi$s;cB_H4$U>sSKmU~}sYSUgOlpJ6O7$0Vc3-|vxb=)Q#e>s`SC<*Kil+n(rTA?rJ z448)QgJXAaW{9_%WF*R7bjXD%80Rt-J}O<%<1N|t<{ATT6PJJr+u>r@Q5N?&3Tp#c zr9Yu*;-lu6%&4wl!Hz?L1wUi81XBXXodRdaX6+F{FN4O2>ASB|F5#wbW*`#_%i&m4 zZ6UvBbsvD`45Ir;@DXgSvS92O&!5afT%tmiL!~>6sfy z{O<-5M6d$Ot-QR~PUaDO83}~}&<`@@r%OJus=ZeA+BaZb*C18m5r>XF$ZpISflPMt z8jP-3mEHwz2KXC!x#%jb7v+pFJvO&@hqKQBGJysd-*kCPneRz#ae7sDxZDG@w7q~Fgtm9j8ZQZG(u*AQEZ9$QUFnx;lBrZh*^Zki@(x1L43kk5n1TY^GvM8ULS~%8;{9eH zoyQ*8F@P8Ci=9Gb;F`U<$bUdF4W%sWF0Wil+=7C9Jcf93MK=(VRM2qzk_V3W8ki&m zD6U8qZ)@wD{5_L$z%Bruf_n+t7=4z2-a1a0zPgtfJa&50g%VfjGL@ix;I?=~l`QT! z#)Tb5atm<~nwltZ2?XN&2Ckk`j-YZQmMGy4C=5zw{)%o{FNh2Ki*oRktuSKWgF`%q zSGk-lJ=WvBAWK%@PEuxHUi{i~WGpqA36lI4o&<47vP~@tV9Mwn5DEfe z6tG*2(<7o)T`r`!zzro>GFcGQe6(;A%2Jzc-p6X--MgPQqpx2;UM?@M^PnRHXdxJ* z=u;nVyxp$ZTj(&FlqB-6xpU36#K-%^8i@UI)xjHVBQ z(Q`4S0c4REF;~}zYY_990L$P76wLetzmzf?fFv6BBIrbUWg_cAMLxu9h(kV+=)22N zlMm|K#MByg6dDHHK(!ze0I^`qz6`g8QV`ecI{+F)@i(C--^pa6p+Q7@zb;44a~yCG zf_y3U5MQWrmjK8?=JEFSmg~K{fHtwlXxgUj{%l{^3(WgCg7!gYc*VyZWDeTnj1J#Z zTE9}_tlw$y`13t|BQkT2mGwQ9t0$tY>R`8cby8jZCb{RSkCcS6ks}CW&BqBRF`03# z61MHqaOnGU$-JdVGTmNg;;h)bTYSHEqff!phylpTxCYw4(cX3}K=bmqf2VCF49^w$ zwy?SomuTU0_*x9R7kejZ%qy0Rw}4^wa?n)pYtD)9ppQWHjM1~Gy?in{mew{`wcR|2 z40=oA>g7`Qr#*nYP0J*SZ9~Mepz3TaVvbYPC^=uf0Ia5@L7RdaYf=@BW3DPbk9pId zdQBp=8)sK>-qVnH7V>8iQBrRT8F~KfBb|#Oe;9((OV6Fsn4u!>K7;kx$LRTsH&RZc zug#y~u`YY^H@AydEbt13m%E`&`od2czTf1w8)w|g@v(HAzS_5Mm)VC9%^))XWq?UKLL<}-kxK-XCbd_sO|ZmF<-Khhiq-EiPu3q zrp985--;>lK#l)C!`sSL^7ES^AkR2^_1%B=Y|({*W1oJy(KM~St~>mu(OpSi2h$gC z8h`xJ+=`NXaDMjI;embVGJIKTCtddNVwmxPW*7jL7DSK5;cNPASO#Fu-!SMi_7Q ziM4^}@kwvQ58+GhNAVw~itYOn&E54>gsV2BrhTNj;c z@u%kh%CD8`&miS9YWl3>+7-8o-liu!Md7UPm5A^cPU8}Krnvci2$ESqhcY_cN`3=+ z)97dCj+=d~b@rJc>eRieAve{-=kx^C{5#!EE$~oe>C@+~!qh}a-LLlwL#aWsuAKbY zUib-B-10P!tnWdph-6%bjk{>*EkJWfJ096bLd;mx6QTdRJjxpw%+3S$5U0~)K3m6L(*JvN?vY`K=0kVPPo zNqTVd$7M%+LC3cnl5Q$IU!SAw-iGDgJ`PD;PCZ;avJwi1XbviYjYqS|Z$zFT{_un{ zz;4OsIig3NR&+~mLh)=hk{+KLa*NYx(i{UmLtTaCyz8!Nvyv+ck%?xv1ji z-*MGP{W?Db_eslB?+#0?Ugx!qs+DlPeU%Ek6{0z~S8DKxRequOtOEhCV8wMv$AS-G z^LXnsIIM0-D24sS5GD zUF-Cc8zEipE8_R0mvvQ~)b>ir|j@1~b?`kHRj`0*mktnFf5Ay*B>JlAjMz#%3wLYOMz*CK1 zdh38&osK-oKdyG58r>?9{T7c!Rbi_i&>TWm8-?9eiqJAs@$^bNKbmQ^P>enKa$Jk4 z<{(@cL|v+|F&QK+{YCpW>+K>YoAAW$f5M z(VeuHiyuw9=}WVyw!d1$CshT1uVr+%v0iUUI|_{UuZ+CGceKyyLWCl^%RVPpCxV!N zS=y$~q{rPG+bNYtZ@*mVl$YrX`YZnZC}a@d|_->aUik=Gb39 z7$cHZCY!4uR|t#b3>xENCS$oOn`6-y1#g+`wi0}FmPw>nD_RouFfAUAYj?WK##?2- zJ93UsGry=-0>6SE4kAM}`chjZbxVL|Uu7LoyPcvvTwKdLb zLs$9^U0k;~#2c}cd`&3J1_T6lJ0!RIt?*1b%SFe}BB|nOd*v|nyseKalXy7B0L(#B z&`!GOmRM_@goQCV%hPDWY%Nc*HQxEaEIc4RFazPQmAV!2)q0*&Yp<2W_6T)11qpc5 z7mrpL9X}J@KYm}#P@>XT`{U2RCzjo*_orcRW;!YKjP~`pSON0t3Oa=gdb=JVlwV-3Xc!6yBT zM>WRgDSBlsz|xo>fg9&sQt|F-T;FpjD4H2;&1IuJ;iz1($Wm|M6qmG+gtTD zo7%Tyym~vQOG^>Wlz{<%W=5%&JS@5!oX2oS-c4TBbjO)MT?&Ar$2Z+nQq}_fN8LUO z=~bm2#2aUY?bDYjz&AjIoNZi`n z-B&}d$dp~;mFo*DmvH=np397N7&gs`t7jmdbpEu?C!@ZVvJT(@eo;{#V<;xHO5rdi zj>9b?n$m$I?BiX}j9=ZyMAVsn`ga6vPy@~J*ou`ZQlkGj4%OKZ$D!bYG;)d zIa5#nGz%tMmHlKy@o~k-<|k@Mc+}1oUVPHSD?yvO8gRN_1-GC9- z!Ni}!^V6hu0(JYX+5+E}B41cDeN9LJN6%a|Lu%94eYUyssvFAJ;$KdS$27PCDI1eL z;Y1t2Tx585G&Q6Mr@yUccx)MCx>VcDe710=<2F@GQr~T3HPlE0@f%R;?@4ike&2Of ze0-}p%#oZZRrrGh&TX`cIp)PWpJQssdcP%#NW$jUPuH-@D=+}NJIGd!)s%J6g-j1B5SE=x<&tjOL51-VZn#0q4dV{-mulC_v z8iUGP-$Gp`rCM~cTi-BX*!AZn@HyW!q8J8o_AHR}KRFo=H~-%V2Q`LPsTGUo?{m9} zu8*2r+vtAN$iOtL4_<}OUxdSBFfwRLTU;Zk&&ancen*q^);AcU|Ex~VeMr4aqA*>~ zgR9~y-l#1;aMBQWs*5B^&@Ef|ii13z-7K)_4mr?W1gK;TKsb!}+@sW!I?@Gu=e2$8 z=7U$}%{b{2*>}(V6A>)6_SP*P*W=pP3U{PPO!}ER#ber++IRDhiUq=p@l;mdhlpHV z(7(Pg7H3hm5f^9SS}PgI@*&>BJ?Bgk<8@-YrS4U5`hxx=J%3?m_&djAKlO0MnN~Q^ zwggjrq+Sf7UF(ZRhn{hs%p(FuMun?C#X zthKTJ_Kdrf6lT&gY|mo1l@&u8wA5a(k|sZ=E_x@vosS`AY145tiE_@=HNuta+M99$IzycI z42-m^M&E-p(^ zM8%U{9OOUPq!NvHL#B>|ciJPkH}`&MlY95{{jNR|A>DH`lzl{&Zq)d&IN~E1n5~d} z4XhQn>a{)_e0q-@6)GCd@ve9@#)a7ES#I=Jt*d(WZdg>Mh<~S)>-?vA@wYUlJX_1a zMQeIv3N%1Cgm=YI&lufS8|;0zh$#aI2V;+Sq29!f4U`9FcUmAp`YSqm?k?hS4<{!~ zU621F0sSlfrDEJLg(oxAspqFO=F2O;hlZY@d6wN8J!HiNH?K@)7F61(a>a#FXC+h& z&wT!T%9KOmxnKs#WP_77i`!a)YQx8Klw8E*2AQGQf`Bd$8qNS zpPtoQJ1+U_nv&_VQVM9Dpz~MG(d(M-PrJCV3W#?+JO8lPUr#Pbx9q zak#+e0^q=TR>nrwn@s#@W31f;FRdlW5-2`tf9#}BDRKaSLyzYXyx8=)lRHz2n{9d3 zYCvX1H(Q+8UhjUv*^SRFyQafZAo`cD!hpggKOiFmg!Wz_l}JBQ&p*^8U2RS%^ouso z=CihQ->Cm2)Ge@J#V7S-=wy3-K7xkh?F6#?Hw8lsBxA;s^`{A&Ao&rVVo27dwEo0m zq>FErPrh)whhM6@@@(7XS>?3}vK`tyFZU2o9^NISg(mJl3Wj;`i+V{sc9v^l-#?l< z#+HR--*%^rGeh0=ENDv(P-L+6mWtB5<}!+*LWO>z~K z{_M+R&!wHXjs-d2B+AQw-iWqD-magW7Y(oQWTfH>8==io<()i~dw$~`TRp<#l10{q zB0Ag`?m~Y(S!lI=u@HZOw|Z8HG%4fUtTCQEIVJVp^Hq(xPV9cXy2tK4R4Kper=YTa zr>~J^f&>fljR)4rK8?kqFZGISJMKnor3P=VSEfl-%CVZh`-HRF7-eq8qX1qYQ@|}# z=W*U!_9Iz~E7iDPN{8r(1;3QRWx}U1RV}&sOsU@YMC(7_zWUI9G~i7HfM@{yI;rx& zm%8uYN%8a-R%$DPlVG*0A-IH(yvE20(mj|Lv*OHJzPYA52;6Zj5^TBXzbK75w$U4; z5lk)TcVAiwThsBQ_m#0&LlQ#(xWNONzD*l8P~_dL)J&2FCXkI;`SCUzMjGraoNjpp zT~Uh=i;eE4&jZGhZRO1G}+Y3o+I6x?+A zg4_Tchk#9xRwHLNNl1<|(m(Xnnt75;9ySxM_R7=Ivi6m$a}Y?~;-4>ci{#hw!;H}z zV^re#)1+tG{RC(tk;l0D_CB)@gwNB|l$I;6&Z~3=GJ!2GT={x;lZIto13On#3bW(!6rk z82LMBN9G^yyBFYuYzl=treD@y9828CC(j=Z(flIOKk;LdEA2`8_QX22U8BfXuqC0Z z6O&ie-Va`7=WoA@Ppy=2GZy9GA!+16L4-96WYuE0`lNI2O?->H2a_#Q_si1-s6!a5 zB#buiIfu{rUex%quD_hwR{J_-K(!RAH-LYsIrL`dB}c4F1kw-Wm`ouY0}<#;pxeH< zOUi+~#dE*BM&c%U6DjM!dOnxAe`E>&9a(?e=zUx?f0)d>U>bm@0D5pB^$*YpX_523 zOeNE?-faljjPv*v+cF(;Om#dm!M`7ac^nA1(?FoY7^xQ!OVI3zXe_`_yl?*9QdEd2#H+`Rxd(EbP9&_?oK z;D%y2&;tN)!*!tT4~~=}`!8?<`!ED<04m&zA|x+z{Rd=Fa{n)I0|%r{|HnRX&}0kz zKj4P%)agAJigGF#jOhXK1s(yw8g{W9|JCpg1;IN}2+m*$VGQ;oLh0}7{f9=eV}R3r z<3gejW1JI@Hx2Fstqx*EWaeMy+W;vy#9yF?o}Inz_%9xB>Vjgis$mUr9e^4F25U)= z`BfTu` zbkF1Ew=_=;my03HbBQr8ZgvBl%{eJ#{Q(aG%xpKoKXag%tTMF! zpG=8e6$KoLzf1|B0fd+mA3)x`5aXi!+XYkN_b;(I-}7XKmHkuJnc`EPOAon9OU$bQ z9KqzG!;)|yC%lSF?oqEGtg&QFL*kg+_(Z{>^4c&0NL{7XJA?pH;shc};Dt_LN_L2@$CSXiJD1u;r zbU(;6;sV3=ka9N5RozEV{sq0V}f2pa8W38EtjBk)vtv z3VL4k#oYq)62J%E+cgJWLGko(%!QB*Knd(AyM~UjR^3U}32afLaHaU9J=uG=zbXhYd`SFcMPbPO3?PPcOi+DngS-4i^>y zJ|+UqDaQx>!<6|nxbFfn0d<9ks2osdp35n% zI3^Hfd6DB|?>9;tFp^8kY=Jm*3gGCm$qr@XOP1aV9^@{dPKc{FAc63!X+(*A0gw~| zzzna*z!U@ig!K^)B-++uQGn-X;^vxOm+)$B(1nrM*)n_S6?NqN#MS3ouDdlaF=+`# znsi7OHP=)=P$xmzdR%A0@+HwiH-=(gj&X$888Rx$@=c+a0FEI_a}&zF$gL~(A7#QF z8aHv2%;JDw3pPZbE!OaV_s`m?RxB;2P9}_KWjR2fe37 z5q~Qj-L_l_TzoTNbE%@>z%?QP-iWSpmj{@WXMiC=Ww34j(Vl7$aHGL!4nL`OnE;z! zJ!tHk?9ry_Vle-n!Ua`si*3udV50welN0EF8h+P_f==KHP$S@S7vDaO1FNi9feF;* zdSJ?A%!OV#S;ICN(3)boLq;a$JRwM-M}pW}^thQFTMt~vyOO|`L;+Rh>X#PIqriXo z2+-ZYh}l2o(Gu7a_=lOGh@86ARAH022uEJf*I#}xtl4)q<07~U8~c>8-FV;L-5_yY z#uOk+9zZL^5h4O|VP>t|v}Tcb4w8WP9Zf+1N%44xgvU0|ok7N+_$Qjo+YaD+m|~ZV~eT0Qxi7Y>}RvLwoUfeix<^ zjtltu^BnBaXBctN$9zA}?2ygHUA!^sH!lDSL!}FGfs`1*%~XqXe4f|o!h{RpzpYW4 zU}o>&EH}h=lgY|Dc|I8pT^m3Ysayfohj#n*hqE`yK~+m;*Tgv0Xy z?eZ5X;RTQqR)}Ny>eB^Xo%>_Jkq^}bJAV0 z(7XQeS$FlIoq&Hhx7X<&^2!AtB1-!l7~En0D&Ka7z2ozK*;Wv|P6Qs~S@y#>5NqO2 z6q&Vd;-YGzhGbncr(xa%qQ1F0CSLyXyY_*{xrD|)Ij4KWb;4=KU6^%m;E;V}tr zy0&=S(V$!-MI~+t8E_o{tEMCp5K}t*bTmU5V#=u2trrZ6vnU}nz-?nLATA)WBBnI3u+RM6c(FO)7q%vI4tFZa(nn8wP*Y)}qzgMs@qFwZYPX@SU zSot%!{g1NO`Cy+C7YNw7ZFcI42?cU*a1W~hfEVMZT3r3&&nabapj(W0*Hv_Imw(O| zovS?ajh0i6^b)6?Co~1ZOvz`cm8V#urfzG&y`{4__K;L~@=?Gqn`Q1aU=uGZB<5T6 zEJ{-+Z0`Mlit0*>it0A=B=)64>88;5@9O^B>>%VJxLijwr`Df)zehWJfKX?CFFtIL z0YXZ!LP!Z>0_j5J@H*4(H^NZTlS;2@} z`SrC;Na1qwe?9nMfTi7$?rw@`zE~_3MW3#df zO``8&qb<=IT{V3=1NMDHDceMSjb6pebRT5ISQyniol5;6trhAs7wqCeN zEZ7>>av;goWQvuSxV>DKXuM61a>}?ya#Cih z-#OxvhUqF8Us)8b{`CcHmCN)6wq}9U{ISszak*TLx;TZUJ)$zqr&kI0Ga6$*Y+v&- zZ7htc(hDk#m0!%uPPrMrTycI! zw&JtLAT-H*k4ugYmy$oo{x!v1?)MZm^19*pBjjLX%7<)<}@=>MHXN+6djw{PXr~LJ|zzm7?ih z6-oOXHM*(s!RK#W44W<^#FkG-T<{#y zd)+cCkV`1E<#J|ok%j7^y)&#6<$4<+t^X|Vo$=7TIM2Y3VZdZ@f&Kp55v3W>dg8qvv;5d%;Ze8SCHBQe6R%x0@ zfcAb~`@1DVH}fOU(b}=+X=zy}RCM?aU;LV=dzeqa0y&7*cq;$Aq!5pYMH5h)$|%rfQ*Npigfa_!9N$lej*;;Fi_?yvWY-s93ZKi8)nu#mfZ>mc>eT?zs&fOAa1JGN!a^V-1cY{u+* z>tKrtll}qj(u&ya7?PC<(F2!th^x~=2(yciNlP`$DYjVw(jeud0z_AWPF9|B4l*-Y z_G4mSiuND%q5%#9WMW2A^qZ7hjr++hfAcF#Ey}nCD%?~sVPMKq{ir$pwD#&ju9mGH z359??yaC))m8ip8 zvLv!bYdDB0VvH0tkM86#1u;gTPsU`2dc%u{>&2 zN|g*76vp{p%y}DK9SJcV0QHcnCcCN?>+XU%<@-g}x&_!7to zBnGtkmnoUs%0Y3-Wad)+#=Aa0Hx2cH1{nrvnfomAaSnJdApz^ne75Kk=jfTsg*F3@ z3m|VG+LpJJwCrh%$EL>D7nXvl@QL14<-;%;+kH= zd3)&5S|#y?wg@027{I-T#`m>Z8O(Ev^q4cq_+zeddexj9RVzWf2}nRY^U7<|dbcML zEN_&|`$~7}VpZ*_9*Kb9R+6F*LXKPsCFq?x{@v-Mbwl&4ue%6B{o;zWl8Qrq8TRM3 zjIdxaKo_w7zFX3$#M}tt1L6{LGLGQxx;u_Qf2A@_3#hU&6>Zkl!&j)V?^%UkfK$Mt~ z={g>eOTkH7b&9a=3PEy&B{Q9FMaVR$;kloCs0UMqRg z1P|(j>uo}~e=Y7#6HS&&tME9My%Z6V0vfWXAY6@zMltBgd_hbI@Gh_2onmtZOR4o*}N!wxtC`K~*KF!8PSo#nyj$=(M;1q=fERs?lT}(jC#gwOo^xkG6ID!Ma)xJ2ru z-xBRc;+=|PFJKF1d{ z-q?a3ASJSv8$X`6nP!5s4kYt8<^{X;E~Cfo4o4f{8mb5304dS#BxZuQcRTmj6%nRH z!_jMo$ta{9s-RbLM1-k!*+bOS=&8FMdi&CHB44eXi2pi>;mqDGSlbX4rUQDgU1qww zjfFl9CM)|%cAFG?(VTvqM;Ud!MvA6^@I8}9t0Q4j{IdSifaBMPyf{32f1}IXG0Mm5wO#6<+4@(d@}8i?YGp{`fYx}j-9Ap2ZFKN5-0y1{a)Ef<3*j>K zi>72An#TArm;!fuRL-@t^@#=KUZb-W=v~C3cO)$UQo^>!5aXlpXO5XJiC$ZICf#p- zbgxnjUg_mL$!Dht6!83t%=H^>Z`Q? zR(vTP9SN*QX2+@CUV3C?=C5g(G6MRnGN-G*Lf3 zJU=ejJE_O!khpH>tMO4%;xGOIZzn7E3wkJni$Xa*8iOf?6O(WN&k~~zfK5cHfX%tQ zgFZHzWZ5m#daoP&7~v^Qa=y+V-?mDdPtJvMKBv8{T5g)a%1$=Fl2(F^_IlPDav>%b$D29oY93`I#K=Bjzg zxX(O3iuEan6Mu01D55Vt2FMsRgkXzW;5YI^GiN$F$`zjl040<=$o>PA7}S7E))sTP zHBhwujH2M*jh(50llRHmE3-G=3Kio5lcw)GpqYC@I9%H>tsi})mbmy%OF5a{-&5O1 z#HyCdG(YNRL~>9G>1LyPwX9LqCE zMhSF-gH$!q5i+`NUK7e7aY6NPXSPi&7IeIBLc~=Y5)S8bI*ldF9-dKnr61>=Z4bUN zlcSh1&;3f+u(%F7qU!S;weJaz{ZW>noIWog52ZmT7#_*Fz9V{qQ{fs6N1sq5xZnrYK3F9UP@nNO!P3^MPsBNQ<%maqz9AjDL2wEjr28?sda z%s*=?&ek?0RsO;XslxVym4F`|)MxO?KVhEJ&0l|};nDB9>VmZgECpBWm`pFZQDLE0 zhI;oxc4WM2k+;%ZhD{{1kq(1y04P!Tge%~cG{)E_h2Thpw-_=2+No}H|Mf&(fr2(a zH6ct48~U)gN~>}k?vc0A-Ol{b?t1U#(FeP*d$GZFn)!R@^rLAjtI8dx9LkYmg4)?? zL+xjX9it*RoiDJ;Uv@WGnA-)Np)&}5EBh$Jqs}gq4o{#9-5R0nso)fd0@nKwI}Zh{ zb`|)&4B?!fM{B104MS-wKF~q5Zj+)@CtLa>>w2ksat(u+8gP!iV1`PZ9d2Hz(&c zch<0U4Zef@NN#MufntuGE(3wj-uv5r=jdvbfh$pjdA42U292Pgr#CD31#BtEH6 zVb<{BwdHOzu+zNcJoWAD_!*RGE-te%m5mV`wjyxasIa^4j4&X|eJYP|d-+V(dBv12 zgR2+xT9L}U^fs4hSWAd6wp{QsU8jnAeS!LRBX2#tS(8*CH&EdedW@-3bLv%xw-*R zg6je((VK1NK7L{vS1jt5Omx+xZ~eE5^T0K;=sz5K)+|PxX==P4_Yy2GJAL{CuwC5C z6+BnMBc~8lEa-})<;K#HyIs6iW|1G@P06Wg-%OZ z2jCzVty)Q-r8R}An>XSq=RPV^W z!3uX~EE-JrjH-X=!D4B$1Y+7Am;m_dA0=ZHHq59la1t~uSSvoI!ha6(wJ4L**xh7g zoevj#QX<|79}c`xG9}#C99^A)zZkfG2}ZK@?FfVditzJ z`mAQgtQK}w8#}9;Ij5I3r=K-vkUeLZJ#UmVZ=5rKFL&M~cm96fylLKoY5sy){(^b_ zg2k7G2L*po9u`s_6;dpVC{{%j>%VZ6$GAnCuZy-{7oQX_+LbKXmn=DyEax7bV zR<`6+zU*AS>{7ApTCx1Ra@h?}b;naZs;Doksh-tTuWu{f-&S7LtoYQdyslmGtzCIj zxB9kz)xUoAUBl}8CfbK4T2K=$xS1BxLJw`Bhkd7qf2T+M)k^=^x)#~C7S*;E-M$vn zzJ}^p`_!@ixpO_Xb3LwW9o@Yi-@TsDy^+|nk@Oc~Bbl&~+Pj(7yNT)BOz+>!=-- zI~5ZN(`-H{)-lhG%rTzZp-vi6P2dTe@sK19-eiK&@#%KpW=m!&Phg0i^ z)9Z(%^~0HsBl70a?B>zj*3tad5#{Ic;`Z^<_VM!0F?IKNW%p!t_k{NAg#Opw$=cq@ z`u@qr{^{oa>DKSlp9iPg2d6uSr@s!*ejT0d9i8nTpZz{QJ2+t+{&mVYI%OQ6GEUAI zr)P{a#vjI?|CctlKmR|8GI+GSpV|97b40vx^>IPy8Qe1kh#rA}9DqLnS-{`?ZzuqE z2H+1Es$Y@a7Rr7>+J;b()A11^ZkVB8ncEd3c>Oth&B8sJ;bhHk3@`A z7f+VkbwtBdm5|KEE@NM9i));j*c_Moutv3Iv!B?nRLu6*me1pqE*RGt)m2bBA`Os1 z$F-G9J#kMR?ittPsr^2j@}CFlt5#c>krJ)O4b}895unT2K*P5eEt+QinfFfc!IO2b z)}PE|*ZiDsP2Yl>G%5e+ZA*~(uZ38;vpSMDnPD1KzrQ}kW;j2DZ4BC2=wM{|&NVk3 zt%i0L|93y7_2^(bM{l98rR6N2qoR9$IO{Oz1i-3n{sAPQ4E1J07A z31cn&y$~+wD*z0KA_XlY5D|x#ARb>A2S2vRqQ&S~EN#)7x8lkYs-oFN+`X1qwDj3! z-*+iCb?3@*+`m9q2?uQ?&e25gAFIiDQ{6Q6*Cr3a4^ie$xcnp=#V^#9$G%cdW_HO2 zj!{nw40zu<)fg={2io+l=o$kBrmox z%WQc5$0c{L-T6)w;^oQb+>{Ku_@`i}$K|z6dN?AbWbA`jzte7?*%y>>i)@cUmruzh?hES;{ornRw4Jx1beWrNzcemP3@qyDqM*$H2iys~NHp)>W)Uw{{xwL6 zlq@@3oMRX7gImP4J_TEBh(^oDIF}vW9IVC@F3MNa4-%|10j$UYx3c54d7sc2F>}Z4 zT-JYO<6~}?thO8~rUuxzr{oQHImIKhDTX&2B)``yrP~Czg$p_odzJbgmHXW+&Dd#7 zZ0lip#&RzJ|7m~OdCpi=NzkQ3bTIMfokf!0s5XnK@BQR>!Jx|ilT*npZYkY`VIKY9 zM#lbmL3jDb@e${UDYFil99@fAe7rWek?3feyHm<2m@|Vf1F?|i=Eqc*xaEu zSA#gSX~uTg_Yo$vCQV&*5Wp`tK=}u>qeim~I>(qMP&jS9m_>0h5l=`&mSg!lqAQS# zcl?IVds8~0&$Z4AEb#Cq=;sNK=SG{1>xvBFMOd3OMC|y)u8tPwU6p>OXIG&sTzrKC zLPLV`Qu8hp@36pdeV-gLW~_)DJ^8J6mb$kx)t4m1er11(77X-^eOE)kJX_7YLDGw}I z&p8?NCsahTZ8AIYS5|_Cltd%@e8jH%w&ptIhUqBF+b9)Z;fAXt*@#n4{OM-e{AWar zm=zCKyr_vhQY-m`SFj?auF;a+raVj@#gUUK(iMwzj zn49okLR%p&!Wdh`$x?8cxpoQ%!6}4dNY&y9Jm6~BnzlyCWr#8VqAV>X#|_3WE{fN( z2q$o-v%0Ah)@{KZ0FHH^ECH6P|b<97?B+=#~HR5^jPl~L=QwRZeTYx`li z)*@TE_#D~O{qVj+zyoD@R7Yk7$7`6Ij$(dr_buPh(Clc$wMGqln`#Zc#1d`&>8zWc zzM&+$B@;)$;Fz#Hw;-O8>ca9`^t^1xH$E;m3*+D!Fj74GBIc_5rTiarCJ;{5wh%8# z{fPyRi((i10IDf7-yM7qk|M3p*GF$q!xL-u=S1^D2^F@?3{lAsS6=>U_Y|!Pc_a#{ z8)1x}w73x#kP0qW1AE`ZaHj1wo4kea{_ekPLC)s`z5fsSFUvx>4f_S~`%C=K&BNIn zU-AyQSL8uKA>XX0{M)D0jqxY;yAL{;&yRX)!X+YjQ)166P(ovR^~P9nejVJmx=^KW zK3%MCO;R;^A_ebk75O8s$11F0NtZ$ykJxi+`n9q1$%I^JQfGhC%8WejC73Ov(XDkL zcmsrbA!wIbyl$5vu$B$pJbopT?GuLvi^(wpf-`4LS%gf31o-{z`CQaW|Iuz^;m^Lz z;$+FPOX_7|9kxO&UL8Sps&H$S1j$L*X(>RBP&ZIPa>3672N29L$rCgPW)CLCAxxNb1#)~{4kX$edpy>okgUBEkPX#6FR8nro{ldZc z*q)VXdSi*2H^L0LmwgLBNuU*x{4*CeG*fB@VbM9H)c`HM#8y%t#Q92v!+UsIqgVTx z)SW3|LH&xn?x0m?`Rt`f*E;5OJ>odL(>NCzoY-y!7AZBY37?~hr35hctGPkpj~?c+ zHh8t?GIj>~$z%W_*+(<9#D9sENJ*-g9dtSqilo$0lDu6^TZN5D2QExWji$98L59PR z$qhFI>ii^)+?Q13vNa5AmoG$L2(y(L6WK-%@tLM^jwH{h3oYnMy6R0 zFWSho32o*63Y2c!&Jc>UO(UCL_392XY0h-zp>zAP7G z@4q?`+Vrci4PUOEK26Uaj$}|ou;YtmO4n))%J`1YNUY(G(duEiam241WJLF{nTX~^ znB=yhkRlkz ztjWvalI#&@q7mWRtSdWQsBx|pGgfy?#D-+Jy^Dc^9b79fmZ8Ox4 z7wSPGYE%P^vH%Y$>y5C>db&haOu?os^+|Qn9r}nni_r@N{Ru(XQjs2Y3Wh#JmHIt> zT@XVdz+Y}Kh4nMSQL}EER*!D z(3Y;B_w*4JVraxsl9*8P?qSranWKdY+U0H1a%z%@6+-qP**Pl8P9?QWpSxngj6niYGPgdp-a-SewvVL8Zj~rB$dYAn}(#P z&9SGY38kbPq<(Tu{Vx)egG*C0z$m$5R)MK+t)kz7V|}9HYa>(iq*A?m(*toyAHbLu zV!TRXVpnCN+<0QwPNE!N5-~Wv4VNBjkP*&!`}rg8^DU|Lm|jd09TQ8(Mu9UEq%yGv znJM7(UMY;cLAttY`iebv9*3#IWq#?+%u;b?KFXx2V2-WQPv64fu89Xy8O1nkX)m_i zH4`nAy`z%-%PPAzDkG0Q%TOxI#2{<7Ey-3WbxI}UbSnKH0|dY>Yc(p1(wn_R&)%eG z3Q6aP80Ns9=SbsndHQnc^xSoD-kDV1Y)*z;XGSL_LlT7T6vawvV~2rmxyt#%qztGq z7TyPIbwX(SYwF&D>NjW@-hvu8XqY^QTCF8vIDI%KX7CR-^vNK&Iz}MXBGz6 z_r^3%7s(wLZSMe_rE@bd*v#X+>|?kG&H-7M7b9I%*jIq_&nb+!oF0wBevLy)C;AHG zuHVAlu*Ti=$0@&kzV)%t>uW)!VNsQJRx9hfTI)~s{^&-Iq-Ou8TN+>Mo_}pHENr0{ zwn%?bvWCJCOe_9nG)&oAL)k`j*(9}8lB0~$0DIh^VHBycB2E<(Rw~`zpD{N`-#>{WZMsdOVb~+DW=v zJf=#fxQe(_0VyuxU6)f_zoRrGjEK%I6aIFr_>KDSw-O$_m`EkqNZ!Wi&XW@%yLVN0 z(yKb9VXiY(+9y@UGkATO8fl{%-Trb>kuQ6?lt;P%;)mpuins|{~x0w=E&Kmpl zZ%&+5hb2h$_X)JgQ{l;0FFH@WJ0?H=el=nFQ%e$ub;wIeV zrsDOK>gWbvMsc;DNK=PdV-06fx{(|L1x)3?WUBVKhE66+Ru zTNr@m{u-K3~m0@H9)(i-T{k?qtYw;Pnm8=*SyohsZvJr9I-fv$HMyLBBo zbf}he@r8D2Z*+mjr0g=f90IOAe&?QVX`mwL0$8eg`m@W zDD7R0XB#~(O+EIqgh@>T$eutBAw-oBi0y<=8-zZlUJ$x8enSST)r$`3tzNA59_X#h z?PUY@l`#<#14{C_q;gS^t@J*3hrZ&CJ`BF^9I`*wJh>WbSEF{NBBS4_soyN5zr_vm zfNQ`^ae&)?z$0Yfe9pkL_JP5T0V}3Kh}ppCfY@E*!G?fAt=vJb_Cd9H_#BjHp+vl0 zZHSxLM;*BICTfV-G^9%%5&#ZYULJmqO{Fxb}%;t9mg8{&W(fV9~(A6=~W(fp^Skw++9_d#Ly?HWM!5eQj-3+X9}#Sy(hHx8D>YUA zbUy)W79Ti0kvNUHXXM~MjcuOR#*gK|)G};IK_JZ{TjRoJl72p^3}#RYo8bn{R5$Bb zT(zui)~RWp5lxhE+?+8Qn`xiDorN{+I-BXllJ8%i8Mvx6bVgQUorUE|@VL*a zR85gKuN(1_X9wlyVRM@QPRlUOExXHkVCTfD<~CpoD}!RRv$=7_!M#8QYwvlUyvx5z z=ZhDoesqey-kiU=KL8H74!UOGq9qm?a7P&Wgzv7IRD{Iq5DwqgSi^-}Al5R0_=GGlS9$f;)7K zX)pOYBU|{Sx7rt*Xz$=1n_P6qOeK92y1@=W5=FlOqGg;D5NF6C81y6)g$<)MZ^|Ug z*nH6(9ekZ$>TwYWS*wrlt^6$H{aNN#;CeNBJ;(b;(`R8!ri=xAqm@Tm$$sOvJuNDC zgLijHP4UN&hd7Jpn5O21AGbFp&6g3pe59c(tm^BfXv#cX27~~zXY+qB;peCTbUoSH LZb1Nn0M-8kh=sL6 literal 0 HcmV?d00001 diff --git a/spec/fixtures/files/attachment.gif b/spec/fixtures/files/attachment.gif deleted file mode 100644 index 89dd73ad3e9fb61eaf4467b9d44c1c9cc9dff16a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30184 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 Dt->n% diff --git a/spec/models/media_attachment_spec.rb b/spec/models/media_attachment_spec.rb index 89916f9f50..2da9d8f28d 100644 --- a/spec/models/media_attachment_spec.rb +++ b/spec/models/media_attachment_spec.rb @@ -90,7 +90,7 @@ RSpec.describe MediaAttachment, :paperclip_processing do media.destroy end - it 'saves media attachment with correct file metadata' do + it 'saves metadata' do expect(media.persisted?).to be true expect(media.file).to_not be_nil @@ -108,16 +108,29 @@ RSpec.describe MediaAttachment, :paperclip_processing do # Rack::Mime (used by PublicFileServerMiddleware) recognizes file extension expect(Rack::Mime.mime_type(extension, nil)).to eq content_type + + # generates blurhash + expect(media.blurhash.size).to eq 36 end - it 'saves media attachment with correct size metadata' do + it 'saves original style' do # strips original file name expect(media.file_file_name).to_not start_with '600x400' + # preserves original type and size + expect(Marcel::MimeType.for(Pathname.new(media.file.path))).to eq content_type + expect(FastImage.size(media.file.path(:original))).to eq [600, 400] + # sets meta for original expect(media.file.meta['original']['width']).to eq 600 expect(media.file.meta['original']['height']).to eq 400 expect(media.file.meta['original']['aspect']).to eq 1.5 + end + + it 'saves small style' do + # resizes but preserves type + expect(Marcel::MimeType.for(Pathname.new(media.file.path))).to eq content_type + expect(FastImage.size(media.file.path(:small))).to eq [588, 392] # sets meta for thumbnail expect(media.file.meta['small']['width']).to eq 588 @@ -126,6 +139,59 @@ RSpec.describe MediaAttachment, :paperclip_processing do end end + shared_examples 'animated 600x400 image' do + after do + media.destroy + end + + it 'saves metadata' do + expect(media.persisted?).to be true + expect(media.file).to_not be_nil + + # completes processing + expect(media.processing_complete?).to be true + + # sets type + expect(media.type).to eq 'gifv' + + # sets content type + expect(media.file_content_type).to eq 'video/mp4' + + # sets file extension + expect(media.file_file_name).to end_with '.mp4' + + # generates blurhash + expect(media.blurhash.size).to eq 36 + end + + it 'saves original style' do + # transcodes to MP4 + expect(media.file.path).to end_with '.mp4' + expect(Marcel::MimeType.for(Pathname.new(media.file.path))).to eq 'video/mp4' + + # sets meta for original + expect(media.file.meta['original']['width']).to eq 600 + expect(media.file.meta['original']['height']).to eq 400 + expect(media.file.meta['original']['duration']).to eq 3 + expect(media.file.meta['original']['frame_rate']).to eq '1/1' + end + + it 'saves small style' do + # generates static PNG thumbnail + expect(FastImage.type(media.file.path(:small))).to eq :png + expect(media.file.path(:small)).to end_with '.png' + expect(FastImage.animated?(media.file.path(:small))).to be false + + # scales image + expect(FastImage.size(media.file.path(:small))).to eq [600, 400] + + # sets meta for thumbnail + expect(media.file.meta['small']['width']).to eq 600 + expect(media.file.meta['small']['height']).to eq 400 + expect(media.file.meta['small']['aspect']).to eq 1.5 + end + end + describe 'jpeg' do let(:media) { Fabricate(:media_attachment, file: attachment_fixture('600x400.jpeg')) } @@ -138,6 +204,12 @@ RSpec.describe MediaAttachment, :paperclip_processing do it_behaves_like 'static 600x400 image', 'image/png', '.png' end + describe 'gif' do + let(:media) { Fabricate(:media_attachment, file: attachment_fixture('600x400.gif')) } + + it_behaves_like 'static 600x400 image', 'image/gif', '.gif' + end + describe 'webp' do let(:media) { Fabricate(:media_attachment, file: attachment_fixture('600x400.webp')) } @@ -164,35 +236,15 @@ RSpec.describe MediaAttachment, :paperclip_processing do end describe 'animated gif' do - let(:media) { Fabricate(:media_attachment, file: attachment_fixture('avatar.gif')) } + let(:media) { Fabricate(:media_attachment, file: attachment_fixture('600x400-animated.gif')) } - it 'sets correct file metadata' do - expect(media.type).to eq 'gifv' - expect(media.file_content_type).to eq 'video/mp4' - expect(media.file.meta['original']['width']).to eq 128 - expect(media.file.meta['original']['height']).to eq 128 - end + it_behaves_like 'animated 600x400 image' end - describe 'static gif' do - fixtures = [ - { filename: 'attachment.gif', width: 600, height: 400, aspect: 1.5 }, - { filename: 'mini-static.gif', width: 32, height: 32, aspect: 1.0 }, - ] + describe 'animated png' do + let(:media) { Fabricate(:media_attachment, file: attachment_fixture('600x400-animated.png')) } - fixtures.each do |fixture| - context fixture[:filename] do - let(:media) { Fabricate(:media_attachment, file: attachment_fixture(fixture[:filename])) } - - it 'sets correct file metadata' do - expect(media.type).to eq 'image' - expect(media.file_content_type).to eq 'image/gif' - expect(media.file.meta['original']['width']).to eq fixture[:width] - expect(media.file.meta['original']['height']).to eq fixture[:height] - expect(media.file.meta['original']['aspect']).to eq fixture[:aspect] - end - end - end + it_behaves_like 'animated 600x400 image' end describe 'ogg with cover art' do diff --git a/spec/requests/api/v1/media_spec.rb b/spec/requests/api/v1/media_spec.rb index 2c29328087..df20081fef 100644 --- a/spec/requests/api/v1/media_spec.rb +++ b/spec/requests/api/v1/media_spec.rb @@ -134,7 +134,7 @@ RSpec.describe 'Media' do end context 'with image/gif', :paperclip_processing do - let(:params) { { file: fixture_file_upload('attachment.gif', 'image/gif') } } + let(:params) { { file: fixture_file_upload('600x400.gif', 'image/gif') } } it_behaves_like 'a successful media upload', 'image' end