BLENDER_v223REND P1SRd< ISRscreen l\LLlD =DATA J DATA JL  =DATAL J  =DATAJL  DATAJ\DATA\J  DATA J\(DATAJl  (DATAlJDATAJl(DATAK|L  DATA|K, DATA,K| DATAK,\DATAK<\DATA<K  DATAK<L DATAKL DATALKlDATAKLl\DATAK\ DATA\K DATA K\lDATAKl \DATAlK DATA\L \dp{D;BJDDDATABDdCIzաD\????????| m===o?p=A|A??p=A B? #<CliggDATA@\D/9DATALLl\??Pףdp{D;BpOI{D{D\,DATA\AzC̽̌?zC@ #< #<`jFzD OBzC̽̌?DATA>,\??? ???? A???PA A!O?j?}GCHB? A B? #<Cli@h@hDATA@,D/9SRdIN< SRscreen.001</|/)(4LlD =DATA<J<DATA<J<=DATAJ< =DATAJL DATALJDATAJL DATAJ\$DATA\J  $DATA J\DATAJl $DATAlJ/DATA/Jl DATA|/K,/<DATA,/K.|/<DATA.K.,/<LDATA.K<..DATA<.K-.LDATA-K-<.<DATA-KL--\DATAL-K,-\DATA,K,L-LDATA,K\,, LDATA\,K ,, DATA ,K+\,DATA+Kl+ ,\DATAl+K++ DATA+K*l+l DATA*K|*+lDATA|*K,**\/DATA,*K)|*/DATA)K,*l/DATA(L|%<LGGDD   !Cdp{D;BJDD'& ,jDATA'B&DdCD#?8bCC(BDC?z?LleOBDATA@&D'/9DATA|%Ll$(<\AA]] '= '; <=!d;BDD\7DATAl$L<>|% l/[[XX?{@AHM    .>dgD;BCgDgD"L?  DATA">+٪^?^?<{vG3N?.=^?x깲+@?` ?{>)Z3S@@$/.}uL$6 Av!AQ>K?Ӵ({#; @>]1gM_vh8֟YVJBw?8A(@?!OSA B?=CxЄ=li L\ DATA@L4l$L UURR'.=Op=o?!!  fd;BPEFRF=5 q qDATAX=G: Lx p?DATA:[8= SELECT IMAGE&&&&(&&I,\\|K JDATA8>7:????=0t??Yf2?|1X:0??@1t@?'.=Op=o+ƽZ:o ;?(A3r%>[Ap[7 '5?@/t@??(A B?=C?=0tli DATA7A,78zC AzC A #< #<`jFzD OBDATA,7B57DdCDv@CC(BDC?z?DATA@5D,7SAVE FILEFILEd:\pete\phys1905f02\nov26\\tics\top.blendlendddtDATA4L<>l\/mmkkKY>Ss>o? !  ! .dgD;BCgDgD2LO  DATA2>|1??d½T/@??9~2?ȯݱd=0@T??KY>o;Ss>i%W?~@25@⃳C昶d=0@T??5?5~@ B?=Cd½/Tlihh DATA@|1D02OAD FILE/9DATA0ALO|1zC AzC A #< #<`jFzD OBDATALOB0DdCDv@CC(BDC?z?SRdNISRscreen.002<0o?uub dp{D;B0CKpD\_,\DATA\_C]zCAzCAbb A@FB= A DATA]>,\\_????????8=i>o?fffAD&@??fffA B? #<CliDATA@,\D]AVE TARGA/t1.blend9DATA[LV,@Ko?{{R dp{D;B0CKpD\Z,WDATA\ZCXzCAzCA1||1 A@FB= A DATAX>,W\Z????????8=H>o?fffA*@??fffA B? #<Cli>>DATA@,WDXAVE TARGA/t1.blend9DATAVL[,LLo?{{Rdp{D;BpOI{D{D,UQDATA,UAlSB̽̌?B̽̌?RR #< #<`jFzD SQB̽̌?DATAlS>Q,U????????8=>o?fffA@??fffA B? #<ClizzDATA@QDlSOAD FILE/9SCLl<SC1liQPQr-@L>dd??< d??_@??////render/top.avi//#,|PDATAQ9\Q<}DATA\Q9 QQaDATA Q9P\Q eDATAP9 Q liDATA,LDATA|P OBli6eOBCamera L}$APzE>@???h?z??:>^?g+@??????@B9q2L?z3$N2?[i4{=44?dC?)d??>)d????|h|hDATA, i<}DATA`|h i Const?OBe6aliOBLamp nM@m@A??????;WP?0YJ{?s>oF>2 x?nM@m@A?????~?=XpͼHc?> u?=(`t>?3oQ?DdC? #=?>=?@???ddDATA,/T3] b?:Y< ?oW<:>C@ ??DdC? #=?>=?@???DATA@^k;6=??\h7m;Vr?2;X_%=y t?d&=\@ ??????rtS3>#rd0+s?H>ZUx? T>qT?d6A @?DdC? #=?>=?@???DATAaME`2zMEPlanelL\`{| PkdRl66)e'kdhr0`kdx н.F>kdOk,>ǰ=kd[:7>죿=b>&c;=b>ⓆU|@?=b>wQ.>j?=b>8/v(ß?( =b>hbJX?= /u]ӲSJ=/e$<"iܓX>=`=/ehBNzF>&y inja`/ 4R%u^/ijǽX>/v_c%=iI9<=0>i)i',?e=ҾI\ v[%?nҾWM\1M>I'Ҿ6*qsCҾBPҾĘ u3lҾ@괭2,S>Ҿz ɾx ?ҾίTJ8>Ҿ@G#-{i?R>_aLه5/>Wu|}<>ʁ{蟾F?>z9E???>jCRP:?, ҽJ?'Cl .>*FJ?ϾlJ?1*l.>"?J?>lDATAs*P  s @v @w@w w@U U@WW U @w! w"@w# w$@w %&w!&'w"'(w#()w$)%w )$u %)u $%@u(#u )(t #) q'"@u ('t"(@q&! u '&t!'q % @t &%p &qu $@q $@t u # q# t@u"@q"@t u! q! tu q @t 4 Pa@4Pa4P@a4 P a4 @Pa u 1 d@q 0@d Aq@0 d @t@` @1 !p  0 `MAq!܎MAblockR `?S?cR>????????L??2 ???\q?DATAP\q??????????MA܎!qMAfloorL?;>_>????????L?RY>2 ???\?DATAP\|???>><?????TE|TEfloor>@????????TE|TETex>@????????CAlCACamera=B?A B?LA LALamp???@A4B>??? B4B?@@WO7WOWorld@7f?%Dq??=}4?b%???Ap?pATXdLTXrotator<*@DATAHDATA\ HDATA\ |qDATA \,b ):DATAl 3x3 DATAl0,0,DATĂl9]*b[DATĂ|9]*b[DATA|,̆<9]*b[DATA,܅|QDATA܅,9]*b[DATA<܅9]*b[DATA<9]*b[DATA<l c[0DATAL9]*b[DATAL9]*b[DATAL9]*b[DATA\ c[0DATA\  DATA \\|0DATAl   v,mDATAl2def DATÁlL resDATÁ|4][0DATA|,́l4][2]DATA,܀|4qDATA܀,, DATA<܀l v,mDATA<̟ v,mDATA̟|</SDATA|,̟lx 32DATA,ܞ|4]*v DATAܞ,4v[2]DATA<ܞ4v[2]DATA< DATA<QDATALL):nDATALof tDATALADD DATA\l[2] DATA\ [2] DATA \[2] DATAl  [2] DATAlLmB[DATA̚lm ):DATA̚|of mDATA|,̚L!]enDATA,ܙ|FREEDATAܙ,IDATA<ܙ\DATA<DATA< reaDATAL|@DATAL,DATALDATA\ reaDATA\ L8~DATA \2][2DATAl  QDATAl||DATA̕l< DATA̕|ude DATA|,̕QDATA,ܔ|L'2]*aDATAܔ,t(x)DATA<ܔDATA<l):DATA< "reenDATALresDATAL|DATAL,eenDATA\DATA\ DATA \\ \DATAl DATAldef DATA̐loducDATA̐|LDATA|,̐\"<DATA,̯|: retDATA̯|,,pLDATA|,̯,0 ):DATA,ܮ|, twoDATAܮ,,.0]DATA<ܮ,[0]DATA<,[1]DATA<,=DATAL< DATALpDATAL,P s, DATA\p)reenDATA\ p.0 ]DATA \\p DATAl , nDATAleenDATA̪l, nDATA̪|,^DATA|,̪%reenDATA,ܩ|\%****DATAܩ,%reenDATA<ܩ% DATA<<%****DATA< QDATAL 0][0DATALL " )nDATAL  QDATA\  DATA\Lp DATAL \8DATA L DATAl  QDATAl (DATḀl, ( DATḀ| 'DATA|,̥ ):nDATA,ܤ|< DATAܤ,  DATA<ܤ DATA<|  ):nDATA<< DATAL$DATALL9|DATALLLDATA\,DATA\ massDATA \H@DATAl xDATAl< DATA̠l#I =DATA̠||*s onDATA|,̠,|DATA,̿|reenDATA̿|,aenDATA|,̿L|`DATA,ܾ| <$DATAܾ,DATA<ܾ I =[DATA<LLDATA<  DATALDATALreenDATAL<eenDATA\FREEDATA\ 6reenDATA \lFREEDATAl ,DATAleenDATA̺lDATA̺|LeenDATA|,̺lgDATA,ܹ|reenDATAܹ,|@DATA<ܹ<@DATA<eenDATA<DATAL<eenDATALDATALeenDATA\\QDATA\  T!!"DATA \DATAl l'DATAlDATA̵l'reenDATA̵|\.ug.tDATA|,̵BenDATA,ܴ|elseDATAܴ,l.a' )DATA<ܴ,reenDATA<berDATA<ADATAL I DATAL(DATALL'\DATA\)CDATA\ erDATA \\ernDATAl .DATAlme )DATA̰ll varDATA̰|0,3DATA|,̰DATA,|lmatrDATA|, 'LDATA|,Rz =DATA,|l-[ 0,DATA, ,enDATA< DATA<Rz =DATA<L DATAL-(RDATAL,qDATALLADATA\,DATA\  ̱DATA \L-DATAl  reenDATAl"DATAl\ Ry DATA| DATA|,DATA,||ADD DATA,\0, -DATA<0DATA<|/ ( FDATA< ,9.8DATAL., 0.DATA\-DATA\ 0,-1DATA \|t ( DATA,  Bile.DATA,loordDATA,̒reenDATARtipDATAl8 ): DATAl8` ):DATA`L6l875 ):DATAL6L`l5=ip >DATAL0mB )DATA<l>'`DATAL=@ime,DATAL="fraDATALl= DATA\,=FREEDATA\ <-%E )DATA \l<,reenDATAl ,<%(roDATAl;2reenDATAll;DATA| ;.reenDATA|,:(rodDATA,|\:/ %e"DATA, :e"%DATA<90hDATA<L9 logDATA<8/\n rDATAL8 %e"DATAL<8. %e"DATAL7 ogDATA\7. logDATA\ <7 %e"DATA \6%(roDATAl 6:ADATAl<6FREEDATAl5DATA|5zzDATA|,,5:HDATA,|4le.wDATA|,4DATA|,<4kkDATA,|3>, IiDATA,l3& logDATA< 3$DATA<2%܈DATA<\2e.wDATAL1@\n %DATAL|1&qDATAL1$))DATA\0%DATA\ l0reenDATA \,0DATAl OQDATAllO)senDATAl O)senDATA|N)senDATA|,lN pi ):DATA b = a - 2.0*pieenDATA \ return b DATADATAdef dot (a,b):EDATA # return dot product5DATAL x= 0.0DATA$\ x = a[0]*b[0]+a[1]*b[1]+a[2]*b[2]nDATA : return xEEDATA,peenDATA,0def vecVecAdd ( a,b ):DATA , # return sum of two vectors%x DATA, c = [ 0.0,0.0,0.0]DATA, c[0] = a[0] + b[0]DATA, c[1] = a[1] + b[1]DATA, c[2] = a[2] + b[2]DATA < return cEEDATA;DATA,Pdef scaVecMult ( s, v ):1EDATA,p # return vector a multiplied by scalar sEEDATAp c = [ 0.0,0.0,0.0 ]15DATA\p c[0] = s * v[0]enDATA, c[1] = s * v[1]eenDATA c[2] = s * v[2]eenDATA , return c DATA,eenDATA(#************************************5DATA(\#* *5DATA(#* now start real program *5DATA(#* *5DATA(<#************************************5DATA eenDATA # setup some constantsDATA$L rod = Blender.Object.Get ( 'TOP' )nDATA$ time = Blender.Get ( 'curtime' )eenDATA pi = 3.14159DATA pdt = 0.02DATA8g = 5.0DATA mass = 1.3EDATA eenDATA, # turn this on to see lots of debug dataDATA,, # in file debug.txt (appears on desktop)1EDATA( # start printing after startDebug frameDATA startDebug = 1DATA< if ( time < startDebug ):DATA  debug = 0EDATA else:5DATA |  debug = 1 DATA<  32DATA(# setup mom of inertia in body frame15DATAL9a = 1.0 * massDATALLb = -1.0 * massDATA,c = 15.0 * massDATAIB =[ DATA[a, 0.0, b ],DATA[0.0, a, b ],DATA<[b, b, c ] ]bleDATA] ]DATA,|# and inverse of IB- note this is only forEDATA,# symmetric objectsDATAD = c/b - 2.0*b/aDATAT0 = b/( a*a*D )eenDATALT1 = 1.0/a + T0DATA T2 = -1.0/(a*D)DATAT3 = 1.0/(b*D)DATA IinvB =[ DATAL[T1, T0, T2 ],DATA [T0, T1, T2],EEDATA[T2, T2, T3 ] ]DATA,DATA <# starting conditions at t=1\DATAif (time == 1 ):eenDATA6 rod.RotX = 0.01DATAl rod.RotY = 0.0DATA, rod.RotZ = 0.0DATAeenDATA rod.dRotX = 0.0eenDATAL rod.dRotY = 0.0 * dt5DATAlg rod.dRotZ = 1.5 * dt5DATAxDATA| rod.LocX = 0.0DATA< rod.LocY = 6.0DATA rod.LocZ = 1.75eenDATADATA< rod.dLocX = 0.0eenDATA rod.dLocY = 0.0eenDATA rod.dLocZ = 0.0eenDATA\eenDATA  print "\nRESTART!!"15DATADATA(l# open debug file if its the right timeDATAif ( time == startDebug ):EDATA( # if first print frame, open for writeDATA0\ if(debug):logfile = open ( 'debug.txt', 'w' )eDATAelse: )DATA  # otherwise, open to append oDATA0l if(debug):logfile = open ( 'debug.txt', 'a' )DATA,eenDATA# check IB IinvBg DATA tempM = matMult( IB, IinvB )DATAL logfile.write ( "\n check IB IinvB= \n %e %e %e \n %e %e %e \n %e %e %e"%DATA, (tempM[0][0], tempM[0][1], tempM[0][2],EDATA(L tempM[1][0], tempM[1][1], tempM[1][2],DATA, tempM[2][0], tempM[2][1], tempM[2][2]) )EDATAeenDATA\# log frame numberDATA0if(debug):logfile.write("\n frame %d "% time )EDATADATAl#get omega in real spaceREEDATA4om =[ rod.dRotX/dt, rod.dRotY/dt, rod.dRotZ/dt ]DATAf (DATAl# find rotation matrixDATA( apos = [ rod.RotX, rod.RotY, rod.RotZ ]DATARz = [DATA0l[ math.cos(apos[2]), -math.sin(apos[2]), 0 ],DATA0 [ math.sin(apos[2]), math.cos(apos[2]), 0 ],DATA [ 0,0,1 ]]DATARx = [DATAL[ 1, 0, 0 ],DATA0[ 0, math.cos(apos[0]), -math.sin(apos[0]) ],DATA0[ 0, math.sin(apos[0]), math.cos(apos[0]) ]]DATALRy = [DATA0[ math.cos(apos[1]), 0, math.sin(apos[1]) ],DATA [ 0,1,0 ],EDATA0L[ -math.sin(apos[1]), 0, math.cos(apos[1]) ]]DATA TDATA$# multiply three matrices togethernDATA\Rxy = matMult( Rx, Ry )DATA R = matMult ( Rxy, Rz )DATAeenDATA|# define torque and force EDATA\F = [ 0.0, 0.0, 0.0 ]5DATA grav = [ 0.0, 0.0, -g*mass ]DATA |/Ftot = vecVecAdd ( F, grav )REEDATA .0 DATAL.# find torque from tipDATA-Ttot= [ 0.0, 0.0, 0.0 ]DATARtipB = [ 0.0, 0.0, -1.75 ]DATA |Rtip = vecMatMult ( RtipB, R )DATAD if (debug): logfile.write("\n vec to tip(earth coords)= %e %e %e"%nDATAl (Rtip[0],Rtip[1],Rtip[2]))DATA̒DATA# see if tip is on floor1EDATAZtip = rod.LocZ + Rtip[2]EDATAif ( Ztip > 0.01 ):DATA7 normalMag = 0.0eenDATA@l5 if (debug): logfile.write("\n Tip is off the floor %e"%Ztip)DATA(8if ( Ztip < 0.01 and Ztip > -0.01 ): 5DATA,L # find friction size- mg * cos( angle) REEDATA,A normalMag = g * mass * math.sqrt (1.0- ;DATA,  (math.sin(rod.RotX)*math.sin(rod.RotX)+(mDATA,,  math.sin(rod.RotY)*math.sin(rod.RotY)) )DATA@4 if (debug): logfile.write("\n Tip is on the floor %e"%Ztip)DATA6if ( Ztip < -0.01 ):15DATA@5 # tip is under floor; make penalty force to bring it back uprDATA( g normalMag = mass*g* ( -(Ztip+0.01)*50)DATA@  if (debug): logfile.write("\n Tip is below the floor %e"%Ztip)DATApif DATA,5eenDATA\# need vtip to get frictionDATA4@Vcm = [ rod.dLocX/dt, rod.dLocY/dt, rod.dLocZ/dt ]DATA1VtipB = cross ( Rtip, om )DATA lVtip = vecVecAdd ( Vcm, VtipB )DATA8lif (debug): logfile.write("\n vtip (earth)= %e %e %e"%DATA< (Vtip[0],Vtip[1],Vtip[2]))DATA4VtipN = [ Vtip[0]/mag(Vtip), Vtip[1]/mag(Vtip), ipDATA9 Vtip[2]/mag(Vtip)]DATA|08DATA`fMag = 0.9 * normalMagDATA0,`FFric = [ -fMag*VtipN[0], -fMag*VtipN[1], 0.0 ]DATA 6Ftot = vecVecAdd ( Ftot,FFric )DATA ̐FTip = [ 0.0, 0.0, normalMag ] DATA \Ftot = vecVecAdd ( Ftot, FTip )DATĄTtip = cross ( Rtip, FTip )DATA Ttot = vecVecAdd ( Ttot, Ttip )DATA0elsDATA4<+# try this way- use formula 4.18 in Coutinho bookDATA *# which isDATA0*# alpha(t) = Iinv(t) ( H(t) x om(t) + torque )DATAL*# where H(t) = I(t) om(t)EDATA )# everything is in earth coordsDATA)`DATAl)# find ang mom = I(t) om(t)DATA4(# first convert IB (body coords) to earth coordsDATA(I1 = matMult ( IB, R )DATA$L(I = matMult ( transpose(R), I1 )eenDATA('# ang mom is called H in Coutinho bookDATA'H = matVecMult( I, om )DATA\'eenDATA '# get left side of eqn abboveDATA&temp1 = cross ( H, om )DATA|&# add in torqueDATA$&temp = vecVecAdd( temp1, Ttot ) eenDATA%`DATA %# divide by I in earth coords %DATA <%Iinv1 = matMult ( IinvB, R )tDATA($Iinv = matMult ( transpose(R),Iinv1)REEDATA$|$domdt = matVecMult( Iinv, temp )eenDATA<$eenDATA ## find om at end of next stepDATA$#temp3 = scaVecMult ( dt, domdt )eenDATA <#omNew = vecVecAdd ( om, temp3 )DATA"DATA "# update dRot with avg ang velDATA(L"rod.dRotX = (om[0] + omNew[0])/2.0 * dtDATA(!rod.dRotY = (om[1] + omNew[1])/2.0 * dtDATA(Lrod.dRotZ = (om[2] + omNew[2])/2.0 * dtDATAL!enDATA #update angular posDATA rod.RotX = rod.RotX + rod.dRotXDATA$L rod.RotY = rod.RotY + rod.dRotY DATA ?rod.RotZ = rod.RotZ + rod.dRotZDATA?eenDATAdRotMag = mag ( [rod.dRotX,rod.dRotY,rod.dRotZ]) )DATA(l>E = dot( omNew, matVecMult( I, omNew) )DATAD=print "frame %d dRotmag= %e E= %e H=%e"%(time,dRotMag,E, mag(H))eenDATA= DATAl=if ( debug ):DATA,=DATA0< logfile.write("\n energy after step %f "%E )EDATA0l< logfile.write("\n om= %e %e %e"%(om[0],DATA,< om[1],om[2]))DATA4; logfile.write("\n H= %e %e %e mag=%e"%(H[0],nDATAl; H[1],H[2], mag(H)))5DATA0 ; logfile.write("\n temp= %e %e %e"%(temp[0],DATA: temp[1],temp[2]))DATA0\: logfile.write("\n domdt= %e %e %e"%(domdt[0],DATA : domdt[1],domdt[2]))DATA49 logfile.write("\n dRot= %e %e %e"%(rod.dRotX,enDATAL9 rod.dRotY,rod.dRotZ))DATA08 logfile.write("\n rot= %e %e %e"%(rod.RotX,DATA8 rod.RotY,rod.RotZ))EEDATA0<8 logfile.write("\n Ftot= %e %e %e"%(Ftot[0],DATA7 Ftot[1],Ftot[2]))DATA07 logfile.write("\n Ttot= %e %e %e"%(Ttot[0],DATA<7 Ttot[1], Ttot[2]))15DATA6logDATA<6 logfile.write("\n R=\n %e %e %e \n %e %e %e \n %e %e %e"%DATA <6 (R[0][0],R[0][1],R[0][2], DATA5 R[1][0],R[1][1],R[1][2],DATA5 R[2][0],R[2][1],R[2][2]))DATA<,5 logfile.write("\n I=\n %e %e %e \n %e %e %e \n %e %e %e"%DATA 4 (I[0][0],I[0][1],I[0][2], DATA4 I[1][0],I[1][1],I[1][2],DATA<4 I[2][0],I[2][1],I[2][2]))DATA@3 #logfile.write("\n Iinv=\n %e %e %e \n %e %e %e \n %e %e %e"%DATA(l3 #(Iinv[0][0],Iinv[0][1],Iinv[0][2], DATA( 3 #Iinv[1][0],Iinv[1][1],Iinv[1][2],2 "?@ABCDEFGH%I#$J%K%LMNOPQRSTUVW!X&YZ[\'](^_`abcdefghijklmn) opqrs tuvwx yz*ghi{+|*}, ']#~#ABMN(#/m%#~)+,-fghijAB&%I.%/:fghiYZ&%/I01!X222/34 %/ed5 6777 6 5 8&4  ' '%9/ de/4 0!:::6 5 "#$%&'(  )#;*+,-./<*+,-./= 01234>56?@>789A:;B{ghiC<D4 = %/ > ? @AA@BBCCDDEEF G&HedIJKLF MNOP6Q%GR'SHHHT 'NUVWXY'Z'[%94I\J]  = ^ _/K`abdcdefghijklmnopqrstuvwxyz{|}~I     GGG2 L+f%&IMNNN']O3w=PQ'LQ#~ NRS M GPOgIT #~(^=U*UU   E  c'TUV  !"#$%&'()WWWXXX*V+ , -%&./01239YYY45V+62/7 89:;<=>?@oZZZV+6[[[\ABCDEFGHI]JK|LM NO^ ^^V+ P/Q 8___V+#R/ST3```U VWX22YZ[\] ^ _ `aabcdefghijklm|b n o pQqrstuvwxyz{|cccc} ~dddcce&eeccccb#        f g%KgggMh hh/gi  opsz tvw x yj jjj /hg%Qq$Jijjj k   lllmmm/nnn'oppprtq 'UVWXr rr/sU %'ZVWXqQt tt uNuuC      !"#$%&'()*+v,v-./0123456789w:w;<=%> Nx xxT?@A B CyTDEz{T/F|GHIJK}TLM~TNOTPQRTSTQTUV'WXY?Z[\T ]'^_` Vab\?cT ]defgh' IiTjklm9no pqrst h'DuTvwQq'TL' xyadz{|} T~'RR T~RT'XY a?T 'S x' G   'DDdghiK- xghi /''& DDDG '!X %2 V+qp3TUVWX'Z'[%abdcdefghjklmvw' R  ????Z T6adcefg    degT9J % T9I  3V+I\/9  %?Th''9n'9'9'   ENDB