#!/usr/bin/perl

#use blib;
use PDL;
use PDL::Audio;
#use PDL::Graphics::PGPLOT;
use PDL::Audio::Pitches;
use PDL::Dbg;
use PDL::Complex;

$|=1;
   
*_dur2time = *PDL::Audio::_dur2time;
sub HZ (){ 22050 };

sub freqz {
   my ($a, $b, $w) = @_;
   $w = 512 unless defined $w;
   $w = zeroes($w)->xlinvals(0,M_PI*($w-1)/$w) unless ref $w;
   $w = exp i * r2C $w;
   
   Cabs(Cdiv($a->rCpolynomial($w),$b->rCpolynomial($w)));
}

sub play {
   my $pdl = shift;
   #line $pdl;
   $pdl->scale2short->playaudio (rate => HZ, @_);
}

if (@ARGV) {
   $pdl = raudio $ARGV[0];
} else {
   binmode DATA;
   local $/;
   $pdl = pdl unpack "C*", <DATA>;
   $pdl->rate (11025);
}

print describe_audio($pdl), "\n";

$pdl = $pdl->float->filter_src($pdl->rate / HZ);
$pdl = $pdl->filter_center;

my @stdenv = (pdl(0,0.1,0.2,0.9,1), pdl(0,1,0.6,0.6,0));
$env = gen_env $pdl, @stdenv;

sub tst($$) {
   push @tests, [$_[0], $_[1]];
}

tst src, sub {
   for (qw(22050 11025 8000)) {
      print " $_"; play $pdl->filter_src(44100 / $_), rate => $_;
   }
};

tst contrast_enhance, sub {
   for (qw(0.1 0.2 0.3 0.6 1)) {
      print " $_"; play $pdl->filter_contrast_enhance($_);
   }
};

tst granulate => sub {
   for (qw(1.5 1.3 1.1 1.0 0.8 0.6 0.5)) {
      print " $_"; play $pdl->filter_granulate($_);
   }
   print " +SRC:";
   for (qw(1.5 1.3 1.1 1.0 0.8 0.6 0.5)) {
      print " $_"; play $pdl->filter_granulate($_)->filter_src($_), rate => 44100;
   }
};

tst modulated_src => sub {
   print " 2 hz 0.7 sine...";
   play $pdl->filter_src(1, 5, 0.7 * gen_oscil $pdl,   2/HZ);
   print " 5 hz 0.3 sine...";
   play $pdl->filter_src(1, 5, 0.3 * gen_oscil $pdl,  20/HZ);
   print " 90 hz 0.5 sine...";
   play $pdl->filter_src(1, 5, 0.5 * gen_oscil $pdl,  90/HZ);
   print " 300 hz 0.8 sine...";
   play $pdl->filter_src(1, 5, 0.8 * gen_oscil $pdl, 300/HZ);
};

tst ring_modulate => sub {
   print " ring modulated with 20 hz sine";
   play $pdl->ring_modulate(gen_oscil $pdl, 20 / HZ);
   print " ring modulated with 1000 hz sine";
   play $pdl->ring_modulate(gen_oscil $pdl, 1000 / HZ);
};

tst touchtones => sub {
   my @h = ( 697, 697, 697, 770, 770, 770, 852, 852, 852, 941, 941, 941);
   my @v = (1209,1336,1477,1209,1336,1477,1209,1336,1477,1209,1336,1477);
   my $dur = HZ*0.22;
   my $env = gen_env $dur, pdl(0,1,2,9,10), pdl(0,1,0.9,0.9,0);
   my @mix;
   for (0..$#h) {
      my ($h, $v) = ($h[$_], $v[$_]);
      $h = $env * gen_oscil $dur, $h/HZ;
      $v = $env * gen_oscil $dur, $v/HZ;
      push @mix, ($_*$dur, $h, $_*$dur, $v);
   };
   play audiomix @mix;
};

tst noise_fm => sub {
   my $pdl;
   print " 100 hz";
   $pdl = gen_rand 2*HZ, 100/HZ;
   $pdl = gen_oscil $pdl, 880/HZ, 0, $pdl * $pdl->xlinvals(0.001,0.1);
   play $pdl * gen_env $pdl, @stdenv;
   print " 6000 hz";
   $pdl = gen_rand 2*HZ, 6000/HZ;
   $pdl = gen_oscil $pdl, 880/HZ, 0, $pdl * $pdl->xlinvals(0.001,0.1);
   play $pdl * gen_env $pdl, @stdenv;
};

tst simple_fm => sub {
   my $fm = gen_triangle $pdl, 16/HZ;
   $fm *= $fm->xlinvals(0,0.1);
   print " 900 hz sine + vibrato"; play $env * gen_oscil $pdl, 900/HZ, 0, $fm;
   print " 900 hz sine + sound"; play $env * gen_oscil $pdl, 1/HZ, 0, $pdl * 0.08;
};

tst filters => sub {
   print " filter_lir(<0.05s echo>)"; play $pdl->filter_lir(pdl(0),pdl(0.5), pdl(HZ*0.05), pdl(0.5));
   print " ppolar(0.8,220)"; play $pdl->filter_ppolar(0.8,220);
   print " zpolar(0.8,220)"; play $pdl->filter_zpolar(0.8,220);
};

tst waveshaping => sub {
   # this is the spectrum of a cello playing as3
   my @i = (1.01, 1.99, 2.99, 4.00, 5.00, 6.00, 6.99, 8.00, 9.00, 9.98,
            10.99, 11.99, 13.00, 14.01, 14.99, 16.02, 17.00, 17.98, 19.00, 20.01,
            21.02, 22.02, 22.22, 22.93, 24.05, 25.04, 25.99, 27.00, 29.03);

   my @a = (.0839, .0414, .1265, .0196, .0377, .0117, .0111, .0151, .0207,
            .0033, .0090, .0039, .0039, .0031, .0038, .0023, .0026, .0069, .0020,
            .0017, .0007, .0006, .0002, .0001, .0003, .0002, .0003, .0003, .0003);

   # add a slight vibrato
   my $tri = gen_triangle 4*HZ, 1.5/HZ;
   my $pdl = gen_from_partials (4*HZ, as3/HZ, \@i, \@a, 0, 16/HZ*$tri);

   play $pdl * gen_env $pdl, @stdenv;
};

tst simple_generators => sub {
   print " 1/f noise"; play $env * gen_rand_1f $pdl;
   print " 900 hz sine"; play $env * gen_oscil $pdl, 900/HZ;
   print " 900 hz triangle"; play $env * gen_triangle $pdl, 900/HZ;
   print " 900 hz asyfm"; play $env * gen_asymmetric_fm $pdl, 900/HZ;
   print " 900 hz sine summation"; play $env * gen_sine_summation $pdl, 900/HZ, 0, 5;
   print " 900 hz sum of cosines"; play $env * gen_sum_of_cosines $pdl, 900/HZ, 0, 5;
};

tst noise_filtering => sub {
   my $pdl = gen_rand 2*HZ, 1;
   $pdl = $pdl->filter_ppolar(0.97, 440/HZ);
   $pdl = $pdl->filter_lir(pdl(0),pdl(0.1), pdl(HZ/440),pdl(0.99));
   play $pdl * gen_env $pdl, @stdenv;
};

tst spectrum => sub {
   $pdl = gen_fft_window(100, KAISER, -1.0);
   #line spectrum $pdl, 'db';
   #line spectrum $pdl, db', KAISER;
   #line spectrum $pdl, 'db';
   exit;
} if 0;

tst karplus => sub {
   my $pdl = concat gen_rand(0.4*HZ, 1), zeroes(5.0*HZ);

   my $dur = 2*HZ;
   my $freq = 440/HZ;
   my $damping = -0.5/HZ;

   $freq *= M_2PI;

   my $e = exp $damping;
   my $c1 = 2 * $e * cos $freq;
   my $c2 = $e * $e;
   my $tm = atan2 ($freq, $damping) / $freq;
   my $scale = sqrt ($damping*$damping + $freq*$freq) * exp (-$damping*$tm) * HZ / 750000;
   print "$scale, $c1, $c2\n";
   $pdl = $pdl->filter_lir(pdl(1), pdl($scale),
                           pdl(1, 2, int(1/$freq+6)), pdl(-$c1, $c2, -$scale*0.1));
#   line $pdl;
   play $pdl * gen_env $pdl, @stdenv;
} if 0;

tst karplus2 => sub {
   my $pdl = concat gen_rand(1.*HZ, 1), zeroes(5.0*HZ);

   my $dur = 2*HZ;
   my $freq = 440/HZ;
   my $freq2 = 88/HZ;
   my $reson = 0.05;

   $pdl = $pdl->filter_lir(
                           pdl(1, 2, 1,2),
                           pdl(-$reson*$reson, 2*$reson*cos(M_2PI*$freq),
                               -$reson*$reson, 2*$reson*cos(M_2PI*$freq2)),
                           pdl(int(1/$freq),int(1/$freq2)), pdl(0.49, 0.499));
#   line $pdl;
   play $pdl; # * gen_env $pdl, @stdenv;
};

tst vibro => sub {
   my $pdl;
   $pdl = gen_oscil 2*HZ, 40/HZ;
   #$pdl = gen_oscil 2*HZ, 40/HZ, 0, $pdl->xlinvals(0,80/HZ);
   #$pdl = $pdl->filter_zpolar(0.9, 80/HZ);
   #line $pdl->slice("0:30000");
   $pdl = pdl(1,1)->partials2polynomial(1)->polynomial($pdl);
#   line $pdl;
   play $pdl;
   exit;
};

tst chorus => sub {
   play $pdl;
   my $lfo = $osc = 0.02 * gen_rand $pdl, 30/HZ;
   my $dly = $pdl->filter_src(1, undef,  $lfo);
   play $dly->rshift(0.030*HZ) + $pdl;
};

tst phazor => sub {
   play $pdl;
   print "rfft...";
   my $fft = rfft($pdl)->Cr2p;
   my $im = im $fft; $im .= $im->rshift(-10000);
   print "irfft...";
   my $fft = irfft($fft->Cp2r);
   play $fft;
} if 0;

tst strong => sub {
   # as done originally by Alex Strong
   my $pdl = zeroes HZ*5;
   my $freq = int (HZ/220);
   my $x = $pdl->slice("0:".($freq-1)); $x .= gen_rand $x, 1;

   $pdl = $pdl->filter_lir(pdl(0),pdl(1),pdl($freq,$freq+1),pdl(0.5,0.5));
   play $pdl;
};

#print "original version..."; play $pdl; print "\n";

for (@tests) {
   my ($name, $sub) = @$_;
   print "$name...";
   &$sub;
   print "\n";
}

exit;

#$pdl2 = filter_granulate $pdl, 0.8, rate => 44100;
$pdl2 = filter_contrast_enhance $pdl, 0.1;
#$pdl->scale2short->playaudio(rate => 44100);
$pdl2->scale2short->playaudio(rate => 44100);
exit;

$pdl = zeroes(4096);
$pdl = sin $pdl->xlinvals(0,20) + sin $pdl->xlinvals(0,50);
$pz  = zeroes(40960);
$pdl2 = filter_src ($pdl, 0.5, 80, $pz);
#line $pdl2;
$pdl2->scale2short->playaudio;

__DATA__
PONNOQSUY[_cinsw{}xurojheb`]]\[[ZZZZ[]_acfhmqv}|wsplifdba`]]^]^``adegimoruy}|yvrpmkjhfdddeegijlnortvwz}{vsplhgfdba`____behkosw|~}}|zxvtspmkigdccdefgiknqsvy}|yvrpmjijjijllmnoqqrrruvwy{}~zwtqomjggfeeefgiikmoqtvy{}}zywutrpnmkjjijkmmoprtwy|~}{zxwvutrppqqqrrstvvwyz{{}~}{xvutrqqrrqrrrqqppqrsvxz}}{zxvsrrpponoqpoprsuvwz{|~~|ywutrpnllkjjkmnoqruwxz|~|{ywvutttsrqrsrrrsttttvwy{~~||{{zyyy{}~~~~~}|{{ywvvwvwxy{}~~{xvtsrpoopppqsuwyz|~|zxxxvvvvuvvvwxxxxxxyyz{}~~|{yxxwwvvvwwxxzz{|{||~~~}|zzyxwvwwwwxz{{}~~}~~~~}}||{{{{{{{{|}~~}}|zyzyy{zzzz{{|}~~~~}}|{||{}||}}~~~}{{}|||}||}~~~~~~~}}~}}}}||||||||||}~~~}}}}~}}}}}}}}~~~~~~~~~}|{{zyyyyyxyyzz{}~~}|||{zzyz{{{{|}}~~~~~~}~}}|z{zzyz{|}~~`b{ztroPPWW @_`?Po7@u/DD   */oT ?g]kXSwР('WȰljbVJOox`DOolXVH;8$'?_Ĵqry~|l\R]aotrlhc]PDOcopidistppnd`ceopil`RPNMOV[kxqrtww{unm`VW_mwp`b[coplrmhb^_gwytklo{|ja_`_aghcg`_aago{tnl`\bgstqospowzts{|u}xlb`TSW_gm{z}xru}|wy~zzzpi\WZ]elpv|tpniknnnjfono}|rjdgmqu}umkiknqtux|tmgfcgkntv~|}tlnhfefoorpsxxz}xywy|}zurqoowvw~|yy|{zw}~{wploou{z}~~zxu{zyxqsyzz|xx}|~zzz}~~~|z{~xyxxzz}|{}wy||{|y|{{}{zvwwtw{{z}~|}|~z{{xywvrstvw{{|~}{}}}~~~z{zxy}}~~~~}yvy||~}{|{{}|||~~~~zzzx}~~|||{{z|||~}|}zwstwvvyz}|zxuyz{}~{~}z{{{}|x}|}yyzyvz}~~~~}~~~x{uzy{yz{{~xx|p`ZTVYXZ\Y]i{}xpopkkmosyyy}tmheabacisy~|wrjfkoou{}}}z{|xpijigjjou{|upmmlnnouyz|~~xsrmjjknuz}|zxtqppoquy}~xuwwy{|zywvrvz||zyxxy{|}}{zzzuwyz~~|yy}|y{{{{z}||{yz{~~~~~~~~|xxz{{}~~}~~~}~}~~}|{}~~~|}~~}|}zxy||}~{z|{{~~}||}}||||~~~}~}~~}~~z{}~~~~~~}|}|~}{}~~|{}~~|yz}~|{~|~}}}~~}~{}~}~}~}~~||{{}|z{|~}~~~}}{zz}}}~||}~~|{|||yzy|{}}tuxwxvuwyxx{ywz}}~||~~||}~~}~}~}|{~}||}z{~}~~~~}|}~}~}~~}}z}~}}~}}}{{}~~|~~}~|}||~~~~~~~~~~~}}}~~}~}~}}~~~~~~~~}~}}}}~}~~}~}}}~~~~~~~y~~owhoyH&7[Գ`K\o@?иd@         +?[cఀrvz{eakl`ZRD(/K_o̨x`D0" &/;G_üX@03G[gs}xhckwظdL@2&   ?_{Ȭx`TMNOW]gihf^P:(%3?O_sx`@  3K_whTD80($#-3:GWo°vnh`XTUYbovlf`XTW^`co{p`XTUZcoyzhXE8(+?Uk¼|p`P@4.'(+/4;EUgwt`PHFGJKJIIMSYbjlmlihgoyȸlXD4( +7GWjwzwy|}~vkdbeefjqytdYPPQU_m{ülb\VSTTUY_jr{xhTD4( %-7ESezĸ|upnnlheb_^\[[YYWTUX\ckwĸp`ULDAACGOYcozzth`YWY]bjr{tpkhikns}|vrpppqswz~yvrrstu}zpdXPNKJMRYcmw{uld\RJDDEINV_m|slfd`_acgkmoppprqqsuwz}rjc\YWW[_ems{{zzywx|~}zxwvxy~zvpllmosv{ztpljhhkmnswy}|th`\XWVX[^cmt{}xwxyzyxvurpomjhknqv{xpkhdacgkmqw{~~~zvsrpooosw{|zywtruwz{||w`exw07oը8(NW` @ ?wȋP6       ;[pTHJB0?wpidXP@:?UoȬxppX@?MOS]ouzlT2/Mkxj`eo{а`H0($#'$#/GkȨl\STPH@61* %3CWkwȨxldT@$#5COU^fupP4 #/9EIS_oxlccirw~xnijrrsuvtoup`\]afmyhTID@=?A@?ACGS_o¸th\L<(/?SgvtdVD=2&$)/7?JS]cegowr`PD:677=FKQWcfku}vnhcegio{}urplhiotyxjecbbbb`__`agjowrh`UI@2,+-3?JWco{xtpjdZPHB<:<?BIOS]foĽ|pd\TNKHLQZagnsuv}xpkf`]_aagopw}{xwwz~|}~~|~~{vutrpoux}xpkd^XUSQPU[_ksyxlbXPJEB@CJRW[eo{xplhdb`_a``^\\]_aiou}~yrmfcbbefgkouz}~~~~{}~~yvspqrsuw{}vrmhijjkmqsuuyyz||}{upi`XTRQSY_emw~{yxrlieeebadghms{zvspljllmnprv{zx{{yzz{}~~|zyxutuwz|}}ywwvuwyxz|~~}}{{}zz{ywuvvvww{||}vpmifegjnqswz}|vvtrsqptty{}}}yx{~~}~|{|~~~}}~}}}}~{zz{{zxxyyz|zyxursswxwzyz}|}{yzxtuuutrux|~||~~}}|z{}~{{|~~~}~~~}}}~~}|}~{y{{zxxyz~~~~}yxyxwxy{}~~~}~|}~~|}}}~~~~{xy|~}{zzz{}~~~|zywvtrrttvy|~}}~|yy{|z{~~~|||~~~~}~~~}}~}|}}|}~||}}~}|{{|}}~~{z{{{~~~~}}~~}~}}~|}}}zx{~~}|{{{{|{{}~}}z{}}}}~~~~~~}}|||~~~~}{|~~}}}|~~}~{opoukop_w]fbbPO_aplup`P@9:6(      7Vcs̴dH0            #/?JWgs̼teZQH@80& '5CO_o¼xmbVJ@2("#/9CNYcnw°xhVH<2*$ !'/:EU_n{¼tfXH<0$
%/;FOZgr}|ph`XRLHFB@<742.+)*+-/27;?FOYeo{pbTH@4,$'.6?MWcmwrjaYRJD@:52,)&$"!!#'+29CMWco{xlbXPE@4.)&" "$&+15;BIOW_fowļxph]TLFA<720,*((')+/3:CKU^go{vme\UNH@;7410.-.149=CJRZ_gqwļulbZRLIDB@>><;:::;<?EIOU]gq{þvph`XRNHD@<:989;>CGKOV[agmsyxrlf`\XRNJFCA@???ACGJOTY^ekszxpjb[UPLGCA?==>AEILQV[bgou{~vqlid`\XTRPOMMMMKKLMOSW[agnv}}xqkfb^[YWUTTSSUWY\]_dgmqtw{xrlfc`[ZYWTRQPQQRUW[aejqw}|xtqnkhda_\YWVWXXYZ]_bdgkorv||vrnkheb`_][ZZZ[[\^_bcdinquy~~zuplheb_\[ZZZYZ[\^adgjnqtw{|xurpnmkihfdcaabcbbcegilorvz}~yutqmifdca`^_`acfiknqsuwz|~{xvtpnljigeeeedeefghknpsw{~|ywtroljhhgghggijjjknpsuwy}|zvrqnlkihgffeegghjlnoqtw{~{xvrnkigea``aabdegjlpsvy||zxtttpmoljkjijijjmprsuwy}}|zxvtsponljjklmnooqrsuwz||zxvttsrppppoopqqqrssstvwy{~}zxusrpoooppprstuvvxz{}~}|zxwvttttrrsrrstuwy{|}~~}||||{{zyzzzyyzyzzz{{{{|}~}|{yxvwvuuuuvvvwxyz{|}~~|{zyxxxwxyyyzzz{|~~~~~~~~~~~~~~~~}}~~~~~~~~~~~~}}}~~~}||{{||||}~}}}}}~~~~~}}}|{{|||||||}}}~~~~~}|{|||||||}}}}}}}~~~~}||{{zz{{|}~~~}|{{{{{{||{{{{|}}}}~~~~~`uovx}h~hpK_t}P<?@ T?  /  ?`W_wHC4/KXIUJCTospH[xhP_wжp8("$!/Ofq{hemprh^fbTQ]wph\L:27?UcsrdXIBAIJIMWen{xhihhkns¼zlhdYSVYYgv{xhVPNJGMU^eo|ty~x}zpbXROR[gu~zrd_`]fjjkrvx{|pjcfku~xrh`]\Z[abeor{|usldcdjjspijkmmz|lea\X^abdo{|rmpmo{xkd`][_fkpv}rmfc``begmy{urnorwpjd][^cjosw}~}yxvpqtw{~xpnosru{}~xtpnmmoosvu}|yywyz||yvusrsspruuvy}}~zxzxuty{}~|}}~|{}|}|{xuwvrryxrw~~|}zz}~}{{|||{}}}~~{{yzxsvwz}~~~}{xuvyzxy}~~{xvvtvvv{z{~|zzx{~zzxxzxxz}}~|y{x{~|~~|zwz|{~~||~~~~}{{}|{}~~~~|~|~~}z|~~~~~z|zxz~~~~|z~}}~~~}}~|{~~|y}}|{}}|}~~|~~zx|}zwxxvy~|}~~{wxwv{z{{z|}{|zyz{}|yywy{{~}yyyyz{}~{{}~}|||~|}~xtsstuy{~~~{xy{{~~|{yx{}~~|zy~~}~{~|{{|~}~}|~|~}zz}~z{{}~~}{{|}}~~|}}~||~~}}~}~~~~}~|}{~}}~~}~~~}}}~~~}~~{~}}~~~~}}}~~}|}}~~~~~~~}}~~|{|}~{~x|zy~po}utxtrlhca_bfbcinps{||vvrjhiqy|~~zy{{|~~}z{}|zxtrruvvz}zxyzz|}zvsrpqrtx{}~{vqqpnmlnoouy||yzyyz{|zx{zyy}|{|~}}~~}~{xwtppquwy~~|zxwxz}}~ywvtrrsvxz|}yuvrqrtxxz}||}~zyyxxxx||}|yyxvwyw{~~~~}||}}~~|}~~}|~~}~zyywvwwy{}~~||zyyxwwz|}|~~~~~~}||}~~~}}~~~}~~}~~~|}~~}~~}~~||}|}}~|zxyzyz|}~~~}}}~}~}}}}}~}||~~~}|}|{|z{||}~|||}}~~~~~~}}|{yy}z{}xw{t}op_p@?oumoаP        ?fwzȬt`D0"'?Seoswzp`PHMW_o|tle^[[]_istpkggiiow¸x`L@2,(%-5:==FUewtj`ZRH<0("+7K_sĸl`TF<1**.7FS_kwºxhVH>:9;COUYbiowxrnpsw}|zutssx{~~~}xrlheegjnu}xi\PFCGHHJNRW_o{p`TJE@<:98:?JS_o{ƺxmfb^\ZTSRLIFFJOYakwzj`RH@=?BIS^gu|xrqpoopnquuzyplheccgkovyrnljihjlkkkilmopsw||peZPLHA>?CKS[eo{xmfb\VRONMORV]ejr{zphc`__`ceikorsw{}|wqlihhkou{|xwxy}}}|yywwtqqqrsuw{xqkgb`_^_cegjnrw|{upjb[XVTTVZ_cirz|xvqmkjhdeeghgkosux}|uplkkklnqtvz~|wuuuutvyy}~}{xwvusrpprtwyz|uplhedbdhknrw|zvtromljhijknrvz~zwusrqporrsvwy||}~|{|{xxxxxxyz{}}~{zxwvwxy{|}~|{zzxy{xwz}|~|y~hkypmsqhopW@@0 7H'Weı`8          ?ktggl`Ugjb`TORJ86KoаX803./?OUWgȨX8"7WupX@       7Kgʴj\J8,!#/9=CKWg{иT8$
&/GWg{¾xqph`VKA95./7?O_o¾laYYZ_jqztlb\ZY_abd``_eloy}p`J<("/?Wguxl`TPH<60.*++/;CO[j{ȺhT@0 )3?O_orh`UPH@8766:CS_o|rmlhgkorwz~{ttqqqquuwpdZQHB@>?EOWcnwxh`TJ@41,+,/;ER[g{p`TLD=;:9;?CGOW_is~ypd\XTNLMNOTZckq{~ztrsppprssuw{}~}}~xtplfdb_a`cimrwxple^[YTSVTY]cimv}vl`XPJFBACFIOW_iu{xrlhbZUSRNOSW_cirz|xxvsqpppssuz{}|wtpnnmmoorwz}~zupkhefedefijmrvz}xnhb\XUVVWY_eksyzxsljfd`]__cekrv~zvtpoqqrqsvvvwwxsy|{}׀?Wgggghhiijjjkkkllmmnnnoopppqqqrrrssstttuuuvvvwwwwxxxyyyyzzzz{{{{||||}}}}~~~~~`K Pߠר{{ ?kihijjjkkkllmmmnnnoopppqqqrrrrsssstttuuuvvvvwwwwxxxyyyyzzzz{{{{{|||||}}}}~~~~~`M  Pߠߠ~zy?kiiijjkkkkllmmnnnnooppppqqrrrrsssttttuuuvvvvwwwwxxxxyyyyzzzz{{{{{|||||}}}}}~~~~~~#O  Pߨߨ~zy ?kjjjjkkkllmmmnnnooopppqqqrrrrsssttttuuuvvvvwwwwxxxxyyyyzzzzz{{{{{|||||}}}}}~~~~~~|zyyxyz{|xsrrpqux~xrmjhgimr{|tlfd`]afo~tlda^Z[_gwle`\ZTV^gp`ZUSTQS_uhXLHHJFO_wȨhL@;;?=K_}Ȥ`D80/77KkpH1( '3?_РxP0 +;_pP"'?kؐh@/OP(   ?oР`4  7g`4  ?k`0  ?w`(  _Ј@  ?ذ`( /o@'kH'_ȿP /_ȸH7oĻı@ ?`( O@  _p(  /кP   ?@  +oȵT(  _̰`4Wи`0 ?Ȭ`(
 ?4 /o@ /o@ ;wȴ@ ?`0
_X _H /o̸P ?İ`@[ƸP(?X8[p@
/ԴP$ OШ@ /oT$ OШh@ 7wذH 
/_P('_Ƞ`0WȠ`0OȠ`0
?ؠ`0?{p0 7o@ /o@ +_@ '_ЈH +_ĈP 7o@ 	;oذp8?ذ`0?ب`(?ԠT OԠH WА@ WЈ@ '_Ȁ@ /gp0?ؠ`0OАP /_@7o`0
KАP 
/_@;o`0
?ؠP '[Ā@7oh8	?ԠT +_@ 
?wب`0'OȈP$7op@'OАX(7_@ %OԠ`0/_H(G{Ԡh@ 3_P0%?wРh@$7_P0 'G{Рp@(!7_X4&+OРh@,%;_T8$/OȠdD0*?kԸP8(7WȘ`@0*?oаP8,7[`@1/Ow̨pP8.?g˸`@03WȠhP60?oʰX@07WhH82GoȰP@37[`H82OwƨP83;_Ƹ`D43OĠhJ83?gȸT@46W`H82?oưR@27]`D73GoP@47_ĸ`D83KwP<47_ĸ`@94KwL807_¸`D4/KwL:17_Ƹ`B4/?w¬L8.3[`B2,?oưT@,/WhH4+;_ȸX@,-OĨpP4(7_`D,)?oȰP8(-O hH0'7g`@('GwȰP2"/WpH,$7_̸X@()G{ȰP4$/WĠhH*%;g`@"'?wʰP0 'OȠtL0 /_hD$7g`4 ?oҰP0OФH"'OȠh@ -_Đ`4/gP(7oԴP$?wԨ@ ?Фp@OȠh4W`0'_`('_`(+_ԸX(+_ҰX$/_аT(/_аT(/gаX0/_Ш`0/_а`@!3_а`@$!3WаhL*&/OаpT2,/O{д`@21?obP85?_j`@<?WİfP@=Koƴp`D@G_lRFAOmİtdLFG[wpXH@KgĸxhP@?So°t`H<?[pP@:Kgʸt`H:=WwİpTB9G_xhP@=Okʴl`JAC[{Ĩl`JDG_xm`MEOg´xpZNCOgzp`LDSkzt`LCSozt`LDOkxp`LCSkxp`LCSkxrdNESkthQHSgvlTPSgwt`RScwzwpXP[oyz`TWg}|{pZS_oxx`X^k}z{t`Yeoy{p^]fs~}d\_gw~z`X_gwxZS[gtTR[k~zpXTbo{yx`[esz{{p`fs~hem{xfiwpko{pmov}lhis~zhdmw|pjozxnqz}rjoswp`ckrxpdbkuzsrimw~|zpt{}|qquztllnqyyp``ioxlldgw|{zvyzu}}w{x{~xllpszzpksu{zpqwz{zpsz|~~xwy~yx{~~vtuwy~ursw{~xoqsw~zxpqv{}~|uv{~~}xz}{|z{xuvvytqstxvport{|xprvw}||usyzxz|{zuwxy|utww|urttw|spruyzssvw}~|xswy{y{|{xwxwz|tsutyyssuv|xrstv}vrstw~tprsw}|vswx{}yyz{~{z{{}{yzz}ywwwz~}xxxw{~zuttuz|vttty~~ztstv{}zvvxz~}}{{}~}{{{|~}zz{{}~zxyz{~|wvwwy}|xvvwy|}zxvwy{~}zyxy|}~}}{{}~}|}}}|{{{{~|zzyz|~{xxyy|~|yxxy{~~|{zy{|~~|{z{{|~~|{zyz{}}{yxyz|~|yyyy{~~|xwxxz}~|zxz{|}||{|}~~}|}}~~~~}|}~|{{|}}|||}~~|zzz{}~|zyzz{~{yxwxz}|xwwxz||zyxyz|~}|zzz{}~}|yyyz{}}{yyzz|~}zyyyz|~~|yxyyz|~~|yxxxz|~~|zyxyz|~~|zyyyz|~}|zzz{|~~}{z{{|~~||{{|}~}}||}}~}}|}~~~|{zz{}~}|{{{|~~}|||}~~|{zzz{}~|{{{|~~}|}}~}{zz{|~~}|||}~~~~~~~}|||}~~~}~~~}}}~~}||}}~~~~~}}||}}~~~~~~}||}}~~~~}}}}}~~}}~}~~~}}}~~~~~~~}}}}}~~~}}}~~~~}}~~~~~~~}}}~~~~~~~}}}~~~~}}~~~~~~~~~~~
