tins-1.1.0/0000755000004100000410000000000012321542746012524 5ustar www-datawww-datatins-1.1.0/Rakefile0000644000004100000410000000114512321542746014172 0ustar www-datawww-data# vim: set filetype=ruby et sw=2 ts=2: require 'gem_hadar' GemHadar do name 'tins' author 'Florian Frank' email 'flori@ping.de' homepage "http://flori.github.com/#{name}" summary 'Useful stuff.' description 'All the stuff that isn\'t good/big enough for a real library.' test_dir 'tests' test_files.concat Dir["#{test_dir}/*_test.rb"] ignore '.*.sw[pon]', 'pkg', 'Gemfile.lock', '.rvmrc', 'coverage', '.rbx', '.AppleDouble', '.DS_Store', 'tags', '.bundle' readme 'README.rdoc' licenses << 'MIT' development_dependency 'test-unit', '~>2.5' end tins-1.1.0/Gemfile0000644000004100000410000000017412321542746014021 0ustar www-datawww-data# vim: set filetype=ruby et sw=2 ts=2: source 'https://rubygems.org' gemspec group :development do gem 'simplecov' end tins-1.1.0/examples/0000755000004100000410000000000012321542746014342 5ustar www-datawww-datatins-1.1.0/examples/prefix-equals-suffix-reversed-with-infix_19.stm0000644000004100000410000000216312321542746025372 0ustar www-datawww-data# vim: ts=2 sw=2 et ft=ruby # Call with a binary number on the tape: # $ turing.rb prefix-equals-suffix-reversed-with-infix.stm 100101001 0. right goto: 1 1. cond if: '0', then: 2, else: 13 2. write symbol: 'O', goto: 3 3. right goto: 4 4. cond if: 'B', then: 21, else: 5 5. right goto: 6 6. cond if: 'B', then: 7, else: 5 7. left goto: 8 8. cond if: '0', then: 9, else: 21 9. write symbol: 'B', goto: 10 10. left goto: 11 11. cond if: '0', then: 10, else: 12 12. cond if: '1', then: 10, else: 0 13. cond if: '1', then: 14, else: 31 14. write symbol: 'I', goto: 15 15. right goto: 16 16. cond if: 'B', then: 21, else: 17 17. right goto: 18 18. cond if: 'B', then: 19, else: 17 19. left goto: 20 20. cond if: '1', then: 9, else: 21 21. write symbol: 'B', goto: 22 22. left goto: 23 23. cond if: '0', then: 21, else: 24 24. cond if: '1', then: 21, else: 25 25. write symbol: 'B', goto: 26 26. left goto: 27 27. cond if: 'O', then: 29, else: 28 28. cond if: 'I', then: 30, else: 32 29. write symbol: '0', goto: 26 30. write symbol: '1', goto: 26 31. halt 32. right goto: 33 33. cond if: 'B', then: 31, else: 32 tins-1.1.0/examples/bb3_19.stm0000644000004100000410000000107212321542746016046 0ustar www-datawww-data# vim: ts=2 sw=2 et ft=ruby # Call with an empty tape # $ turing.rb bb3.stm '' # Busy Beaver: 3-state, 2-symbol # state A 1. cond if: 'B', then: 2, else: 4 2. write symbol: '1', goto: 3 3. right goto: 6 4. write symbol: '1', goto: 5 5. right goto: 16 # state B 6. cond if: 'B', then: 7, else: 9 7. write symbol: 'B', goto: 8 8. right goto: 11 9. write symbol: '1', goto: 10 10. right goto: 6 # state C 11. cond if: 'B', then: 12, else: 14 12. write symbol: '1', goto: 13 13. left goto: 11 14. write symbol: '1', goto: 15 15. left goto: 1 # halt 16. halt tins-1.1.0/examples/ones_difference.stm0000644000004100000410000000137312321542746020211 0ustar www-datawww-data# vim: ts=2 sw=2 et ft=ruby # Call with two strings of ones on the tape: # $ turing.rb ones_difference.stm 1111 11 1. right :goto => 2 2. cond :if => '1', :then => 1, :else => 3 3. right :goto => 4 4. cond :if => '1', :then => 5, :else => 17 5. right :goto => 6 6. cond :if => '1', :then => 5, :else => 7 7. left :goto => 8 8. write :symbol => 'B', :goto => 9 9. left :goto => 10 10. cond :if => '1', :then => 9, :else => 11 11. left :goto => 12 12. cond :if => '1', :then => 11, :else => 13 13. right :goto => 14 14. cond :if => '1', :then => 15, :else => 16 15. write :symbol => 'B', :goto => 1 16. write :symbol => '1', :goto => 18 17. left :goto => 20 18. right :goto => 19 19. cond :if => '1', :then => 18, :else => 21 20. halt 21. halt tins-1.1.0/examples/concatenate_compare_19.mtm0000644000004100000410000000175612321542746021375 0ustar www-datawww-data# vim: ts=2 sw=2 et ft=ruby # Call with four binary numbers on the tape: # $ turing.rb concatenate_compare.mtm 110 1 11 01 1. right 1, goto: 2 2. cond 1, if: 'B', then: 3, else: 1 3. right 2, goto: 4 4. cond 2, if: '0', then: 7, else: 5 5. cond 2, if: '1', then: 6, else: 9 6. write 1, symbol: '1', goto: 8 7. write 1, symbol: '0', goto: 8 8. right 1, goto: 3 9. right 3, goto: 10 10. cond 3, if: 'B', then: 11, else: 9 11. right 4, goto: 12 12. cond 4, if: '0', then: 14, else: 13 13. cond 4, if: '1', then: 15, else: 17 14. write 3, symbol: '0', goto: 16 15. write 3, symbol: '1', goto: 16 16. right 3, goto: 11 17. left 3, goto: 18 18. left 1, goto: 19 19. cond 3, if: '0', then: 20, else: 22 20. cond 1, if: '0', then: 17, else: 24 21. cond 1, if: '1', then: 17, else: 24 22. cond 3, if: '1', then: 21, else: 23 23. cond 1, if: 'B', then: 25, else: 24 24. write 0, symbol: '0', goto: 26 25. write 0, symbol: '1', goto: 26 26. right 0, goto: 27 27. halt tins-1.1.0/examples/mail.rb0000755000004100000410000000246012321542746015616 0ustar www-datawww-datarequire 'tins' require 'net/smtp' require 'time' class Mail extend Tins::DSLAccessor include Tins::InstanceExec include Tins::MethodMissingDelegator::DelegatorModule include Tins::BlockSelf def initialize(&block) super block_self(&block) instance_exec(&block) end dsl_accessor :mail_server, ENV['MAILSERVER'] || 'mail' dsl_accessor :body if ENV['USER'] dsl_accessor :from, ENV['USER'] + '@' + (ENV['MAILSERVER'] || 'mail') else dsl_accessor :from, 'joe@doe.com' end dsl_accessor :to, 'flori@ping.de' dsl_accessor :subject, 'Test Email' dsl_accessor :date do Time.now.rfc2822 end def message_id key = [ ENV['HOSTNAME'] || 'localhost', $$ , Time.now ].join (::Digest::MD5.new << key).to_s end def msg [ "From: #{from}", "To: #{to}", "Subject: #{subject}", "Date: #{date}", "Message-Id: <#{message_id}@#{mail_server}>", '', body ] * "\n" end def send ::Net::SMTP.start(mail_server, 25) do |smtp| smtp.send_message msg, from, to end end end def mail(&block) Mail.new(&block) end def prompt STDOUT.print "Send to? " STDOUT.flush STDIN.gets.strip end m = mail do subject subject + ': Hi!' if rcpt = prompt to rcpt end body "Hello, world!\n" end m.send tins-1.1.0/examples/length_difference.mtm0000644000004100000410000000111012321542746020505 0ustar www-datawww-data# vim: ts=2 sw=2 et ft=ruby # Call with two [ab]* strings on the tapes: # $ turing.rb prefix-equals-suffix-reversed-with-infix.stm ab ababab 1. right 1, :goto => 2 2. right 2, :goto => 3 3. cond 1, :if => 'B', :then => 5, :else => 4 4. cond 2, :if => 'B', :then => 9, :else => 1 5. cond 2, :if => 'B', :then => 13, :else => 6 6. write 0, :symbol => 'b', :goto => 7 7. right 0, :goto => 8 8. right 2, :goto => 5 9. write 0, :symbol => 'a', :goto => 10 10. right 0, :goto => 11 11. right 1, :goto => 12 12. cond 1, :if => 'B', :then => 13, :else => 9 13. halt tins-1.1.0/examples/ones_difference-stm.png0000644000004100000410000011167412321542746021001 0ustar www-datawww-dataPNG  IHDR|4*bKGD IDATxw\3[MJ56JQQ * +ƨk&A7YM#1Xbcl[ (D myܽHٝ3|{YgyfBP ` w`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA .\x5U< t[l]B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B(B.]k.)))ѣm~,Y28UVK&9::2_.Mjj ˝5ksRPPuV~=H8:B0dRy<ޜ9sp+//۷o7₱*0DFFr\A 0G@̘1C.+p8X`322p8666`TDD A:Q!P(t `TnFI ]B0mΜ9 bݺu] @7} H&<~x `۶m;xzBB(p0܅@O˵/'AKo{:FA`Q:FA`Q:FA`Q:FA(SPP}3guUěCBBN>M_Pm%@ɓ'{I_U[[̗}=x>ضm=E `@ (Ya\4rСC{#c@&@zB t/++C 06:uWZeooqFܵA&uk,}}CY@@Q(K,A.BKLLˉ'֯_@ .;v "::֭[ԃxↆ3f.P BP.%%jhhx"3g/ݻ7k֬ VM;otl+ (cddݷmk``zԨQ&M:z(y5bĈ#G9rUC:2ꫂr9eQ "FMpy`Q:FA`Q:FA`Q:FA`Q:FA`端ںuk_P455|jsss_4k/ʕ+=zԥܽ{cƌr*̙3*׭[׭[7B(!!a{9sj-[nŊpJ_W{y.]r 233 xc( t@UWW2.%%Sݓ'O\;w޶G 2]##""$ɁI'O d2蚯Ӈѣ:V?N]p5klذaСj6ɯe2۷?v@=YyyyC 6mږ-[o- \.o߾7n܀;;ZBtJmm lM*444'Ǝf t/^=zTAݹsux/BA耎[ vvv4xORiVVVrr2%:p>,&&& 6/_y<ի: `'SPP0x]vQج[~~oVV)<`VuuuA\xАfuP(|>AMMM䇐yxx$%%Qx86x geeQzzz...'Oζiz:m%KN<9zhZt)SH$ZXamHKKDN@ P(th,,,lҤI?8P(D2p,: ӦMܹs'33ufnncn$7|'411a:vܹiӦ#Gxzz2y\@; %++룏>ZjդI>P(+BŋSN1bė_~ѡS td|>2ccc# ttWUUɓ vZܵ '''%###ܾ*Bz:: `An_uyܵ @ ]`tt}ƍ߾*0TGw@蜼ٳgϟ?kPX\\,qh[jkkLҧOw-oeee ! "22ŋ -}YWXBG[رcj* Cxz+N>vZܵP=-$J}~A~AA̙3#"">c`hϧ]|ygʔ)Bp͸Kk:Z~xR4))O>/))|* /BGH$#GHRPSSSIIIII'|B>b3@PTTP(Ytd2LwEGGd2uH ={ w!^:fmvWWW3_R'X:BG;v\.?+$O͵V?nN Yf}gY<z:Zn$kݻw r{}aÆa`.xYjjjk+>;w?ql=Am6wwwUu@ ~:*=C{x;w}ւUl̬[np[Gk)@' 8k?nkk<66UKEEEmmszںuj4jAٚU() thaCCׯ5 !iӦNhזFFFAAAoUl 6b:;r}||lmmcccB4z5Qڷ O͵v9n8k777B F t6BGAnРA\.!rkV߸q#5Qڷ) ) v- .\iii|?tМ"|]"r9 J:Ϗݳg /W(K,AR]e|$r| \ai%444\2 @Fbbb\\\N8~z k%o!diiijj CD"ʕ+B BFwADtt[MKV:Lضmٳg7 rɑ,* ZxqCCÌ3ꨭSMM thx\ \ f͚6_pE3g466^dݻwo֬Ys"6mv,奭 th7uT2,8Ό3 6_k``3jԨ0"ȑ#NNNTey]Kyi+˜vxRedPP\.W,9̺5@PZZ*Jyyw!J:`,^OOnh^z:ZB >:੹} tWo[Wh"j@"<w!2:?}tB LLLpV>dҽ/RYYzjZ҂rrvrppr?@TZZ: >Ro,a9\.KIGKA0- e2X,Rf!h:y{{7 ~qY`a8p`@7K`)/MᆱG~p<=='M$ 5Ea Nޒ4@ (** *ߟLhxx84P(lhhx)B t0puuEzj\%aZvvvvvvPPB2""wEޞýdÜc\r!m``. r!t4N:XVVo߾}IRБ#GOixj th$Jwݷo߱cǚݼy3<<<<<޽{iiicƌ۷ݻO5-ׯ_>wܞ={'%%X+gذaIII/^ٳܹsׯ____f 5P6&&G\.7""͛y͛7#""\n=bbbjkkSرw@E:VVV|>?***??-EEE|+++X\YYIGZ 55!s܅U@PL$DǏǏE"H$*//Nz*B* tR\\,bӧOjӧbX$Sղhllr]P>>wdKc@ ]2VbTeOO9s8;;edd5 w]m5jԥKҜ̙e]`i0wYD" B BCC_~zhh(AB066V"ஈFuuuA=zw! t Z,x[nuGm۶mƌU i]t-rX,iQ;ҼܹC߁lmmׯ_O_&: S"H S$//Юv%ə3gW|hΝ666WB/ƕwUUUEGG#|||;СC>9aH$ߦjW_uiD"###rWYY vh͚5r\Pz !dmmM߱O>uT4)**׷Ϟ=eBԢgϞb rOQQ%ͶI٥z;g}6p@4ѭɉݻwcT?lذ.!jFUWWXZZ oi̙\v?leeE!t%t9}ӧO˔WHNrppp8׮] b䛊hhh W^>ΥK pwwB˫<<55!'P۸ҝ;wB> tə0aA={_>tjjjrrr֯_okkkaaNCSWWyfr\ĉ)_7c!jUA?~M9t>3CfHՍ/R~OmΟ?occJ6׽{͛7>6OoA``2+!t}P( $ jANӧ6`i"mrV+W¼4bVdvv6ݔ#w LKK# |.˗B-`,Ŝ4򎲋Kll,x$Irrr~~~mܹs RӧO<(ؿ?*XqZZ+ WW)S<|077XA,_חt(tH7n &9;;S8+4 |)SΟ?OIaXgggr7l onҥFFFܴiL&@.MvlsCsNDDdz/_]]^|)ɹZѣA.t@$EGGWTTஈJfff"wEԻqB6,::'ODGGDD95::ɓ'+˗/BO]<\,w֍a*77wE%w֭X,օwͷlق :oxyoy}uֽ{ȹvvv3#W]mSSe˖gϞӧτ pr}={~]l)BhfPK IDAT6/[,??Ν>D(Yݵ֬Y# k%$$丸 2d˖-B8;;COG(%i\S媵S^^.LMM [OJbDDDh]2vعst>}*̌:X$O7-,,|||=zDE?1b*@gAPehhHΥxa^x!>|د_ݻ:u5ط~₻ Y:8qA+W#Gܻwݽ{744WMM {,۷oϗJ CcǾ{ >..ɉʕ+/dff999ũvj\\u:ud@!ݿ G*"H6l@Fϔ)SLp7lؠഴ4;;;77[nٔ*--Eѱ3,Ya{ݻ)kӧ#F044ܹs'Umj\n``g܅NQ]LLL֮]p1MMM(ZNf'ww wS`p v܉?>x111{GY^^px\s C%\iӦH ,̘1#+++55K X@h*?~ѣG˖-(ěZ^zeff~}lA tnܸq /&$$|WW9sfmm-P($.t BkZmo۷E"B4:hР㮈^ӧ С͛===Ǎyw}}}> B:Ԩܽ{EضçMrJL"Z888| tc7o<܅A__?..n׮]6l=zgpWD=.=:mKLiӦ9syYǏ4ʕ+ˡ<5:HJJ*..^t)B:s޽{nݺw9 46l0fwww܅t{'OFFFᮈ2:uٳgQ"'&&;vlذaZ;:ڴiS^>܅t\"J tiP@(~w!:jسgϒ%K3233'N8nܸ5kr6:jٶmޜ9sp";vl޼o d\5 tT'J7op&.?=͛7oԨQ ^HHHfffEEŠA]4, tTӽ{~G ˗4hA@PUUU]]Ul۶$22w!4255=xڵk͚5K#$AtYSSw-"bٲe)))gΜ]QA:,eӧOIygeee 0ȑ#i a9.۸qĉɞptt %NlܸqРAÇ]{EEE߼yԜ t:VZZ;T6hР,r*z:,ӱ8KK3f.DXYYZ~B t:P__믿.X@__w-=zFz z : BZhB4ĉ\B.?x%&- Eqq1Bxeiiу޷o9vSN]  drKy)X = &333AGedd.JX>O.?A̶ṉ@WAO r!P(*++wMW_}'UeAf:on.MMM ӣG4hPbb"4Z``rG}86yCeeeJRЍ72 .,Zhʔ)t/?` AIIIDf~ƍ'LK`:\.f4k֬ Z3.yCee%τ$$$t~wUUU 0`…/d2YiizeZ@輡kX͛CBBԣ5k,X@B1c͛7lr)':wm濺m;vС/"99Y.s89s樼Ja'] +W̟??>>5˗/ϧ83^n;vlFFF]]kL/_\zjm\XXι`ȼgώ5 !dooOP(ܼys]]̙rB\.722R.cV\vM__A TkpРANNNkNT*߿?B/99YPD"ݻ⊊ BnCCuׯ===[MxoCn nfaaH$222211D!___D`s\ru\V@Ǵ6t$Ill@ "44gbAfffٌ >vZP\GEEQ@0tb Nj}v'_X]]b KKK>Ckt??? Z_aYm_S\t5*t***bq D"ѣGThױ'888++:AkcǎWp87onp5NiiH$211122Dj6NDppK(tqqqAx<q##bkͧSTToaa!={Fa㍍B( 11Arss>}WX>εй~DDϷ}MdlODä{-Y\ѱGp5FNVVVpp0qpp}53MKK{BJW5?}k-as%rH{||<{iiiBFkpƄNbbb@@Bw9xL&[ύ7"""8@ s:r>>>'&&b6w툈gcc#pW\9_~#G<="EGGԞsS:... 6{IttrjOii)4kĮ!'8;;s܈7nந˞?"E}}=NYl /_bkkkr͝;wBAAAHHۺu:?dCCCwwsfffv ҫWbccmmmɩ=W6G 84&Ċh333rMAA <ֶ)66H$gΜ!_˺;wp8]zHGGGrjիWUn/^ %k\ӧB%%%I4O},,,._LGiii#GDDa&Mj~㣏>bx"h= Ça:IOO'=<<D_®~Q+wޥH9 X*dEEE۷o'ׅ@mܸ;mh: "44t޽zpD{g&u֭ 333SByjjjrrr֯_okkkaaNCoHKK;v,yC–'Nzw(lm\ws}U')Cf{ B.zW\INTH$:tPUUH$IR [=B(??f纫(9+WoZv [^^^TTdz􍎍0arŋm?ZU9fС4k@ 6n}k1W\AAH$244455DԶuVwwwrL&ۺuw_T#z.L.tO8JNNFZCZs!1]ӧObH$Fzz^kΝ;G@*>}>J理Bbcc{IoygXXXAAjkk8P\3pi9S[nzzzo-#8NO_PPPm5SL9)уxMZnmʕzzzz/n sNjjjbcc8Nhh(,qVVV|>?***//wEJs>..ɉ)d_*//D"Us l됧'B( %%wEj)..Dbӧ+b8:-C" 8w:r~X,ң\Zg+tHr<11!)ݽ{744HAl %C}cU233i5NNNqqq+oee%++++DN!kOMs[aC ȩ=eee | -B06T<~4.ϵƥ)4,td2ٚ5k\nhhh^^X,677'TCP($"44r|̘1\.Rƅ\t ]ISRR2|p##xcbb,--ɩ=ž<׀*4GGG@¿cԞANLQNݻ:q8ղ ;׀ _~?BBo=ڵkM*Oټys;|>ۻTAW1pX: B"̘1P5K95..{777wh &#055򲳳!k\? @n\} 2___ 'NPٳgɭlll >7odϭ#wSSSrb1 g\ۓ䧟~]`Ydgg BWW۷ow==QFڵA4IIIApܐ􂃃 Eff%Ks=t˗)tN8ajj:rH5o⴯ !t!:_jՐ!C?YYY={tssx͚5kĉ4yk֬?~9sOKKK$HBt47dffZYY5322 q\nnnyyyHҨ/~ڸqM122(-ڦ,X 44R;ѣGL} Ѵ̨3gNbbݻg͚ di鴃C {nח9::EzjرɧOf&q!M>̙3/^/**RrssCvBѣG.] dX.p8~~~W^U155]:Çd/^$'0oOx…ݻc%ڭ:a۷o>G  211?"###""6oތ؀w=z۱c,,,>:BH"p\Ϗ[xqEE"ziU:FC#Gӧϱcp5jkk Mk֬qqq?~~~mY.؀+W>rGlqIO~mBddyxxxUU \-Nzo ۫Wȉr=+WÇg,qPJ$BhҤI'O<{qjjjpZߺ"xj=nܸ߿yZv{wSSSܹ{=w9=trrrF흘Ȇ,R8p`JJJiiiHHׯq8NϞ=#G;))%oyyԿ3g?|=h O=֖=X|y;拉=﨣͉ ;B&88:ǔ͗WJgϞ}رc:Zpy-^\\Ķg,RHMMχܡϫqh ?0--ɓt_^)?ətݻw:tLJէWJ?vؕ+WfϞ OQB(x<(?OmTH$! :رc'NOqע |3iW\7oއ~((lZ! >;v̚5k<#{:/^ܰaƍY8mJiƌs΍zZ4l SSS1eʔHj v\^)ϮMMMk00#C>H$ Mk.HѸk0X:g\\ƍY>*ZlzEGG-[;v w-M*vXt9tϟ?m4xFނD"aT:uY.\˹wl QCocЉW矹\.ٲUXc?ӆ lmmi*Z bŊ]ׯ_ojj_9Nn|IZlϦv5jԨSN6 w9TTTobbsNrhУXExۼϞ=v˥& ZXXr \P(R)B(11q„ Xk󓒒޽˶%bYq999Hnp5_Sօ˫ǏlڴIS!dllCUhhرc,X@v@ |=S#H>ɉ(ЧO?7nmyyy7n+Vh\ccA::D"Yr%dԩzzz,XA7:mҥk֬] -_w:8t tޝ0q?dqCիW#bbbpF+Wl `w%mllo׺uqF_T~8NHHtH=Tw͙3G& K*j-/^_.);;pig޽{y<ޣG@8qB!am˖-qPWWףGxSNHtYnԩS{Ic1#z-XPb޼y={;;m200ЁȌj'222BE &L@Akaȯ_ZZ6'oE_|||?M2EP{**sε]7!̴QMMц hͼ^z^VVt¢w!׿L?[om>|\?˗3OM]]3x8coҥ}opBܵtك|}}.b֭]6o {͇3744, 3fl޼YC!}%=/^3\ ŋoݺz[$%%qܐt)%:#FuӢE>} 3_ -,,v؁ ̚\kFgϝ;_ms=3F;wY >.\XRR|X:.\иA\\\ƌv-CG.gff>K5V-:uTnn.BNk:>|,/Ǝk.܅2t_ׯ_?,Zqܹsڵ n'Zݻw=<\SSZNAA R3e2١Cpt#HpUDh"kkkKKŋ744t999~5W( &M 9~t-88Xwh#Gu}̙%%%+<{ !|( HMM%bȑ/_ܻwo'_)pe˖6wIɓ'¸su>!aÆfgg.x!dmm.pBRRҒ%K߯_K۷ڵk|y}}=Q8 秦8qYYYi߽Q~bo?YPPn:uyBS1]FޘxoGڿ?ΚP(Mի{S&W(4ZZ !G?(8=:Ul?!J~K~|J@@@gt$''ԔUwʕe˖9::R3rssoݺEa,'$###$$VOO{l[o.B!:Nyy9B[nd픔dddxyy}7l{C^ۛv}}}>~Sl'D$]p!33իW۶m;p@TTMOoNSSBc*^|200 %㲲R iiiiii|rЦMhUU Dr…ׯ744޽[f 4iSUYY) &M:wwUg}×/_O!j;Ŕ`[a#?LRV" Iq\/B޽{T6ʕ+-,,z"~[4iҭ[=z~SE'jӦMB}O={_QQ1`3grP`` ڣ١RB Z# SE QΆ#?O>T堠 KKK J~CzzΝ;i*RM~iiiׯO?~x5?!VZv}y{{T$Uۗ2z蠠 ܵGC'""!J~={j]z!4}tBǎ#>Bh̘14>iҤ'OP ٶmB?D566R"EN<9o w}ɓ'4K+ ~SL<7Ay :tڴi}{l=pW H{:Ak˖-FFF(GaU}ut&LPWWיLPBG0hĈlh @#Fq9pAP(`@+,  !4bĈlr!hBhذa/.h?Bݺultq* ~?>uԼyvE"B\/;;w!B"ܹ׭[wersbmm CAS]]}ĉUV-\pEEE+oo7oB'888,]\D.*w9w\P}!tx{{CO1k׮ms&rti̡O.eB&&&xlUп\@dR/!!ؘ'&&у|3ɵI1+,,l~~~ X?+nnn2X7^_ĉ97&+FLJJd /abbafagpLQ$tɒ@{۶mV9-|VVV X[ٳ?#|7|?;kggBUX___ 7l_-Z: By|>fff^=**ի ܲe ) WX8::>| +W?ݻ˗?EM2ŋxxt0 { ?׏9|pZZڀ` xwqM]Ož*ą nQjZV՟uઢb*ֽ D@PCe>O BHn%7~3p9۷dW :.zѐ!C<<<|pSN]N7 t? "['&BHKK'AHOH!Xv@>>wss=rH aڵׯ_"CSlmmLgqQ\pB ,,,%%@ tWQQ葩SZ[[Bb#QrJt ߄SԄ֕ëg"Ə8n8P\\ bs!p3k֬KSSSM&fIII}!oW_}%Zs,ͱ0f777,++CIT|m;FݸqIGGGfǏ/m#HAu&cٲe?2:!===GfeݺuFFFx "!ϟ5k0L1qD\JNgʔ)Ǐ2:>}Bb?bKTWW󞐑`0mBXTT$G,^^^b4i$\N 7A e111="&á, /{X!˥hIMM4h$''[ZZJKPGGx ]Y`A]]ŋ{ NB>m۷8ڵk{űBܝ?~̙ⷓ$VH!&t`ԩ! 6˗/>}3fMihh?~BөD\ŋ?SUUCEzt 7+ .LNN.--~ Э[(D_ߟdU$rssutt,--l'--B}?OEzt 7SӧO/bbbzNۛvd@.ݷoϟpMMM\.~YfyF䪸ȳvڟ~Iv.\,~;&:z~s`cccRRRhnwo.֬Ycjjf|lNCC7|ӷo˗׷}ã-OMMݺ"rU\ɄUnnoӦMC19{ؙ&ࢨB$'' [md.tԾ'O .D(.@:{]...s:@7oիم|…Za XǏ| .dd2ҦLBv!@7ܹs<BGܹsdN:B={͛7kjj}&ILS{ IDATL166& f͚f\3!t͛7 HH>}Ǝ+(++{1ٳg_~kX:"11QUUU{?͞=b]vM tEbbمBp8III'O& f͚u zA(NI򪯯hdddkkKv!@ΙXZZ BG!ܼysr<'NLNNW[[ V&Lw!t_jj*Ñ0aB(55'@ȿ7o9wd#ցБpl$t*%%HBIIIqqޡŋ#G]^x ,&Lm۶W^v|бBHKKΎ*Bիd" P _`` %HjzzzC9>>Ϗ8m׮]6mz6ٵ(..B/B(>>B䄫Ç;>tBh,K~3+**222ğ=z46VG:!Իwooo?Bpvee対BqppxQCCCLJ t+444???//BtI&ijj]P8l6;??C:>dȐ( MmmmJJ [RXXX=|C:ZdӧG%&&Xӧ]PPvvv=B_rم̙3d]AAA:՝3gNdNyy /^Lv!@q 2oi'44K}2ɓdmmmmyy9rv\\\ &맓\cTUUɮ(. C[xq\\ܧO.DtϞ=[d مf``QRR·B߼yTLN1bСC.(4 2p@uuugϞ]`م PZZʷBd"Gl dqYYBN=zĈx:e݋/իٵ !t `pi_YYwߑ]!ddd;: 鱱d\.t$g``P__v!N455Ν{ak֬!KOO!TSSv!N-[VTTt ֮]GEv!N~ɍ7VZEv! BBCCϞ=[UUEv!۰aȑ#a UB|@ﯦ&.\a PSSSۅ:9rDO'oٲӓBhGYY!v!N7BCC矴4 Rnnŋ7nHv!hT*Bn :YO'o޼|҉NCXhh{ ă\~z s,F]=___MM͘ իlZfcgvx t6o޼(Cv-;w.55u߾} Zv`E.ҥK_xqm Wss?8w\GGGksu+͘1ct+**~7 K!mm !tz…CۓǏ7o 366&u:C@GWWWJN'o޼YUU.Z)##G~:ׯ: Ё+хz*992.]joo|rr[:h{:wΜ9sRiWVVfhhwKYȨРo>}СC/_L&ԬZjɒ%0R׭[Phh(m455IO.-gggUUU;;ϟ?ST˦&b&_lmؖ{فCv…Ç'@yi.PX,VBBرc̚>QnF}m߾wiĈ `٭@իW&&&| !t뛑rY,ߣY|aN͛7} N "S\\laaBG(ÇWRR7Iy޽X8@Q00E?}dnnηB9tдi:KJJ6lO?YYYItCƆo!B2d5)%ɓ鈈J 6ܑ]dڵk%5|%vSh4Zpp0Yȓϟ+++9ѩ]vظcH4tbbbܹpf.ad#Omll:@@>}455ێFR%:>|Xf͊+ &M(8ѣGΔQTGG[|(((:th:=cnn~M:λɒFI.t.\e BOB^ :.1xTr{:QQQ׮];y򤺺$?|𡬬ֶC:#}}l6=={8qHڜ9st:N={6ٵȉѣGw]\x1"czzz&M¥ALAAA5|p92#f[dooob6rӧ-q{O>Ji;Kw||-&5JB.ۣe޼ys]9|}}.g؋'Iy#ĉmfdd0n.8::u55)TjTTANNN~~~kk+I|R 77[!DFF}!dllZlB())H%Ν;Ӛ:=vر۷oR(-xDX<<>BHjjqRSS6C4pNйyҤI&R+0._u tl}||F{㰧wB =@;o߾W^mcc#!t\R__?""BB_/^oܸ!Dz€=~~~SLV t^SSsNn!;wX=*--o-Z-mAlvPP޽{ ^mۖ%VB=Zvv͛7n8bb*//'l:(iӦ;wNI3-pNիwjii]O:u9+++7 W(ׯ^:""b֬YoB`0fϞ|r# Bk.j@QN6166J%wB3f+..NYYJ򯦦fʔ)YYYzzzĉkkk322$=l0 tgXԤ]B:ȱZOO߾}[JdUuu)SJKKoݺ5h r!//A o=z_]?JffСCH:)Dž Lzybrb׮]gϞ1cƹs.KpԴ`ݻw\r˗/9B7Jnni j̙>LHH `*AEѪ\n6449lȞ?>k֬ʛ7o]PPP&&&cƌt*ڿ+W=ZYY9''GVAE$CҀb\rƌYYY2qO{:4mΜ9#ooCEFFFEE]Q@ť7ydv!F|TVVv) EGt:?dWlC\]])q!??V???kAEEEnnn+W OOO "AƎ?vXhiiYvy dWOAECh4󟖖R5jԁ<9x`R P\L&sK,qqqqqqYdL&ae455mڴՕNgff88m9so rÇڪaaa/_Ė|2,,LUUU[[;<<Ǐի{immP,o߾ TWWpuuuMMͰoJS԰0Mz@E eee==*ϯSVV z9^0p:>jԨ\:@=}4((NFFF nmmmdd!N z\zuڑ r<BȳӧSTcczک466RӧOm, !+*:@>eddL8!4hРflnn8qbff+//_ͥKƌ1bĥKl6x>1c\tIoޫW/CCØ܋E:@N옘aÆ!/]p$9s%GGGаa6pbbbLLLo.25&&!4}tA vgkkNMMuppPRR 22dFFFQ(ӧ߹sJ )#B0a;}t\m Wcc;V^˗/crHzʪ'\*ھxӧOJJJ!!!dWį8$$DIII__?""ӧOdW$] t(// RSSkaJ:aݸԴɮHZ@͛0 J+VeeeDDq ՞={uիWDDćȮH|ݸ={FvEdRɓ'شX:yűc _O555KK dggPER}||Sލ/_Μ9SGGb BHlTDnޞ7k566`k}d~?۷/J믿D655EEEƕ#Nk=ջQUUe``6d###%W"eo++\itVbb"BhРA◄]S3fLrrm ڰa˱-,,$X@ t).X܌9Sx6^K.1Dk0_-ǏB+ndb'N>|3\OOO 3f[V)..F8d:Jrvƌ#F8qk?MF@rX'Nϟ? #++S:'ꮯOJJ;wmBxzzfee1 cc۟8q7ٱ5Fa-B(88XkWX)SSSTFF.Zm 4ɓ' idd$ķ}ƍMMM%'BD7==-:\.h޽$MKK۷/B(<<ߖڒ7 VTTF:tH+B3txܹ9r$~ud؞3|hjj5j֭[\'ܹs!S @IIIXXJ>}"""%-B!_iTWWGDDGEE%,,D[ .q8nׯ_GHhc)--m+L[+t222B666_eeeٸJKKqOѣG---?rlѣG &`߿UQQ y5^-766&%%ukZL&355[˗,2>>~ %..\ׯCBBTTTtuu#""޿c|z7222Κ*ݶsssB/^YTT$~.:;;uJAIDAT{xxN722NKK*LQQ6W޽oNFW_J\vPAA6@^ú&ݻww=sY~D*څϟBׯ_'0 SؽQ2dF 8'_7. |yPP1O`B֭[NNN!Ǐ X622NURaa!a 22G'{ ݂x]r7n\VV׷ƕ'N1X)ccH)::`kk?\ |BXg#G&%%֍!4qD3'33}a``%1a]LL –!&L`0$T"UV }777nPb2tnn iMMM۷on#O:pԩƥ(ܮ0aĺ.[VTTZjd;d PX`ɓ' (.0te˖M2ٳg% 2݄Nccٳg ('''??!C|JvQLݏ_xj<)++ q8u-[TUU\~ӧE%ll;;aÆ:uJ5YrϞ=q '( =GѶlLBBvc1${:iӦh4\ZZ333}||6l؀ zvsO<9zR&M;v,NȈ=ճб^tMjjj$TNϟ?5jTuuuRRRjj E"""8κu$Q B^ 2dH~~3gx N޽|...f!. GD]yϞ=JJJwf Z[[?|@vE@>xxӧO󵴴B@$lm۶-]t͚5d P(Ǐ7668Xlٲɓ'?{%'}ݻwѣG]WA0ovvv/^Ɂ)v߾}{BB. UTTܻw/..pc1 ^ -Zɓ'&&&x5 ۷8p@[[{pc1ߧͅˮ䪫۵k9ڵkWXAvQ o \\\ L@]v555}aaaz"(s ^|8v3g"a7_eeUV^OvQ333s]xqǎ7:r-[6ugϞm߾H'Loׯ_Dd'''???[[[ltKuʕ_9s222$ `0\]]'M}x H? N/}᯾/˓VÇ'MNR FRRѣ. H0th4ɓ']\\BG$i9V\\;r>$%%]= A)++߃ >> i*B֭Qmɟ>}MC9sFszc͛6m搨EE$DztDMa|رfZr]=%iW>aaa؁^uuʁȮU<|L0̙3dW$Azzz!~Ǐ]BЉ FX!O:,`xl0l3g͛0`@nnnNN-33֭[FFF?=Q>'))iFFF!*l2;;***ƍ۽{7Bĉd@gؤ$]vU1&O.c dcO[IIIuuumw#G]tА!C.I8qbڴimblv-XNRIݻwB| م= &`00LPSSSfffۅ=ںuߍ9o޼YlYUUB1%%{=f9''gΜ9CmzKKKVVT1-,,fϞիW,\1nCɝqcW/ϟ?>566v[0w$wUƷ~>rlDIdй#| bNطo߾}.I@.A P:BA P:BA P:BA P:B9r/a@[EBBBhh(YHU (R20@A9 t B@>82̟IENDB`tins-1.1.0/examples/concatenate_compare.png0000644000004100000410000011167412321542746021054 0ustar www-datawww-dataPNG  IHDR|4*bKGD IDATxw\3[MJ56JQQ * +ƨk&A7YM#1Xbcl[ (D myܽHٝ3|{YgyfBP ` w`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA .\x5U< t[l]B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B(B.]k.)))ѣm~,Y28UVK&9::2_.Mjj ˝5ksRPPuV~=H8:B0dRy<ޜ9sp+//۷o7₱*0DFFr\A 0G@̘1C.+p8X`322p8666`TDD A:Q!P(t `TnFI ]B0mΜ9 bݺu] @7} H&<~x `۶m;xzBB(p0܅@O˵/'AKo{:FA`Q:FA`Q:FA`Q:FA(SPP}3guUěCBBN>M_Pm%@ɓ'{I_U[[̗}=x>ضm=E `@ (Ya\4rСC{#c@&@zB t/++C 06:uWZeooqFܵA&uk,}}CY@@Q(K,A.BKLLˉ'֯_@ .;v "::֭[ԃxↆ3f.P BP.%%jhhx"3g/ݻ7k֬ VM;otl+ (cddݷmk``zԨQ&M:z(y5bĈ#G9rUC:2ꫂr9eQ "FMpy`Q:FA`Q:FA`Q:FA`Q:FA`端ںuk_P455|jsss_4k/ʕ+=zԥܽ{cƌr*̙3*׭[׭[7B(!!a{9sj-[nŊpJ_W{y.]r 233 xc( t@UWW2.%%Sݓ'O\;w޶G 2]##""$ɁI'O d2蚯Ӈѣ:V?N]p5klذaСj6ɯe2۷?v@=YyyyC 6mږ-[o- \.o߾7n܀;;ZBtJmm lM*444'Ǝf t/^=zTAݹsux/BA耎[ vvv4xORiVVVrr2%:p>,&&& 6/_y<ի: `'SPP0x]vQج[~~oVV)<`VuuuA\xАfuP(|>AMMM䇐yxx$%%Qx86x geeQzzz...'Oζiz:m%KN<9zhZt)SH$ZXamHKKDN@ P(th,,,lҤI?8P(D2p,: ӦMܹs'33ufnncn$7|'411a:vܹiӦ#Gxzz2y\@; %++룏>ZjդI>P(+BŋSN1bė_~ѡS td|>2ccc# ttWUUɓ vZܵ '''%###ܾ*Bz:: `An_uyܵ @ ]`tt}ƍ߾*0TGw@蜼ٳgϟ?kPX\\,qh[jkkLҧOw-oeee ! "22ŋ -}YWXBG[رcj* Cxz+N>vZܵP=-$J}~A~AA̙3#"">c`hϧ]|ygʔ)Bp͸Kk:Z~xR4))O>/))|* /BGH$#GHRPSSSIIIII'|B>b3@PTTP(Ytd2LwEGGd2uH ={ w!^:fmvWWW3_R'X:BG;v\.?+$O͵V?nN Yf}gY<z:Zn$kݻw r{}aÆa`.xYjjjk+>;w?ql=Am6wwwUu@ ~:*=C{x;w}ւUl̬[np[Gk)@' 8k?nkk<66UKEEEmmszںuj4jAٚU() thaCCׯ5 !iӦNhזFFFAAAoUl 6b:;r}||lmmcccB4z5Qڷ O͵v9n8k777B F t6BGAnРA\.!rkV߸q#5Qڷ) ) v- .\iii|?tМ"|]"r9 J:Ϗݳg /W(K,AR]e|$r| \ai%444\2 @Fbbb\\\N8~z k%o!diiijj CD"ʕ+B BFwADtt[MKV:Lضmٳg7 rɑ,* ZxqCCÌ3ꨭSMM thx\ \ f͚6_pE3g466^dݻwo֬Ys"6mv,奭 th7uT2,8Ό3 6_k``3jԨ0"ȑ#NNNTey]Kyi+˜vxRedPP\.W,9̺5@PZZ*Jyyw!J:`,^OOnh^z:ZB >:੹} tWo[Wh"j@"<w!2:?}tB LLLpV>dҽ/RYYzjZ҂rrvrppr?@TZZ: >Ro,a9\.KIGKA0- e2X,Rf!h:y{{7 ~qY`a8p`@7K`)/MᆱG~p<=='M$ 5Ea Nޒ4@ (** *ߟLhxx84P(lhhx)B t0puuEzj\%aZvvvvvvPPB2""wEޞýdÜc\r!m``. r!t4N:XVVo߾}IRБ#GOixj th$Jwݷo߱cǚݼy3<<<<<޽{iiicƌ۷ݻO5-ׯ_>wܞ={'%%X+gذaIII/^ٳܹsׯ____f 5P6&&G\.7""͛y͛7#""\n=bbbjkkSرw@E:VVV|>?***??-EEE|+++X\YYIGZ 55!s܅U@PL$DǏǏE"H$*//Nz*B* tR\\,bӧOjӧbX$Sղhllr]P>>wdKc@ ]2VbTeOO9s8;;edd5 w]m5jԥKҜ̙e]`i0wYD" B BCC_~zhh(AB066V"ஈFuuuA=zw! t Z,x[nuGm۶mƌU i]t-rX,iQ;ҼܹC߁lmmׯ_O_&: S"H S$//Юv%ə3gW|hΝ666WB/ƕwUUUEGG#|||;СC>9aH$ߦjW_uiD"###rWYY vh͚5r\Pz !dmmM߱O>uT4)**׷Ϟ=eBԢgϞb rOQQ%ͶI٥z;g}6p@4ѭɉݻwcT?lذ.!jFUWWXZZ oi̙\v?leeE!t%t9}ӧO˔WHNrppp8׮] b䛊hhh W^>ΥK pwwB˫<<55!'P۸ҝ;wB> tə0aA={_>tjjjrrr֯_okkkaaNCSWWyfr\ĉ)_7c!jUA?~M9t>3CfHՍ/R~OmΟ?occJ6׽{͛7>6OoA``2+!t}P( $ jANӧ6`i"mrV+W¼4bVdvv6ݔ#w LKK# |.˗B-`,Ŝ4򎲋Kll,x$Irrr~~~mܹs RӧO<(ؿ?*XqZZ+ WW)S<|077XA,_חt(tH7n &9;;S8+4 |)SΟ?OIaXgggr7l onҥFFFܴiL&@.MvlsCsNDDdz/_]]^|)ɹZѣA.t@$EGGWTTஈJfff"wEԻqB6,::'ODGGDD95::ɓ'+˗/BO]<\,w֍a*77wE%w֭X,օwͷlق :oxyoy}uֽ{ȹvvv3#W]mSSe˖gϞӧτ pr}={~]l)BhfPK IDAT6/[,??Ν>D(Yݵ֬Y# k%$$丸 2d˖-B8;;COG(%i\S媵S^^.LMM [OJbDDDh]2vعst>}*̌:X$O7-,,|||=zDE?1b*@gAPehhHΥxa^x!>|د_ݻ:u5ط~₻ Y:8qA+W#Gܻwݽ{744WMM {,۷oϗJ CcǾ{ >..ɉʕ+/dff999ũvj\\u:ud@!ݿ G*"H6l@Fϔ)SLp7lؠഴ4;;;77[nٔ*--Eѱ3,Ya{ݻ)kӧ#F044ܹs'Umj\n``g܅NQ]LLL֮]p1MMM(ZNf'ww wS`p v܉?>x111{GY^^px\s C%\iӦH ,̘1#+++55K X@h*?~ѣG˖-(ěZ^zeff~}lA tnܸq /&$$|WW9sfmm-P($.t BkZmo۷E"B4:hР㮈^ӧ С͛===Ǎyw}}}> B:Ԩܽ{EضçMrJL"Z888| tc7o<܅A__?..n׮]6l=zgpWD=.=:mKLiӦ9syYǏ4ʕ+ˡ<5:HJJ*..^t)B:s޽{nݺw9 46l0fwww܅t{'OFFFᮈ2:uٳgQ"'&&;vlذaZ;:ڴiS^>܅t\"J tiP@(~w!:jسgϒ%K3233'N8nܸ5kr6:jٶmޜ9sp";vl޼o d\5 tT'J7op&.?=͛7oԨQ ^HHHfffEEŠA]4, tTӽ{~G ˗4hA@PUUU]]Ul۶$22w!4255=xڵk͚5K#$AtYSSw-"bٲe)))gΜ]QA:,eӧOIygeee 0ȑ#i a9.۸qĉɞptt %NlܸqРAÇ]{EEE߼yԜ t:VZZ;T6hР,r*z:,ӱ8KK3f.DXYYZ~B t:P__믿.X@__w-=zFz z : BZhB4ĉ\B.?x%&- Eqq1Bxeiiу޷o9vSN]  drKy)X = &333AGedd.JX>O.?A̶ṉ@WAO r!P(*++wMW_}'UeAf:on.MMM ӣG4hPbb"4Z``rG}86yCeeeJRЍ72 .,Zhʔ)t/?` AIIIDf~ƍ'LK`:\.f4k֬ Z3.yCee%τ$$$t~wUUU 0`…/d2YiizeZ@輡kX͛CBBԣ5k,X@B1c͛7lr)':wm濺m;vС/"99Y.s89s樼Ja'] +W̟??>>5˗/ϧ83^n;vlFFF]]kL/_\zjm\XXι`ȼgώ5 !dooOP(ܼys]]̙rB\.722R.cV\vM__A TkpРANNNkNT*߿?B/99YPD"ݻ⊊ BnCCuׯ===[MxoCn nfaaH$222211D!___D`s\ru\V@Ǵ6t$Ill@ "44gbAfffٌ >vZP\GEEQ@0tb Nj}v'_X]]b KKK>Ckt??? Z_aYm_S\t5*t***bq D"ѣGThױ'888++:AkcǎWp87onp5NiiH$211122Dj6NDppK(tqqqAx<q##bkͧSTToaa!={Fa㍍B( 11Arss>}WX>εй~DDϷ}MdlODä{-Y\ѱGp5FNVVVpp0qpp}53MKK{BJW5?}k-as%rH{||<{iiiBFkpƄNbbb@@Bw9xL&[ύ7"""8@ s:r>>>'&&b6w툈gcc#pW\9_~#G<="EGGԞsS:... 6{IttrjOii)4kĮ!'8;;s܈7nந˞?"E}}=NYl /_bkkkr͝;wBAAAHHۺu:?dCCCwwsfffv ҫWbccmmmɩ=W6G 84&Ċh333rMAA <ֶ)66H$gΜ!_˺;wp8]zHGGGrjիWUn/^ %k\ӧB%%%I4O},,,._LGiii#GDDa&Mj~㣏>bx"h= Ça:IOO'=<<D_®~Q+wޥH9 X*dEEE۷o'ׅ@mܸ;mh: "44t޽zpD{g&u֭ 333SByjjjrrr֯_okkkaaNCoHKK;v,yC–'Nzw(lm\ws}U')Cf{ B.zW\INTH$:tPUUH$IR [=B(??f纫(9+WoZv [^^^TTdz􍎍0arŋm?ZU9fС4k@ 6n}k1W\AAH$244455DԶuVwwwrL&ۺuw_T#z.L.tO8JNNFZCZs!1]ӧObH$Fzz^kΝ;G@*>}>J理Bbcc{IoygXXXAAjkk8P\3pi9S[nzzzo-#8NO_PPPm5SL9)уxMZnmʕzzzz/n sNjjjbcc8Nhh(,qVVV|>?***//wEJs>..ɉ)d_*//D"Us l됧'B( %%wEj)..Dbӧ+b8:-C" 8w:r~X,ң\Zg+tHr<11!)ݽ{744HAl %C}cU233i5NNNqqq+oee%++++DN!kOMs[aC ȩ=eee | -B06T<~4.ϵƥ)4,td2ٚ5k\nhhh^^X,677'TCP($"44r|̘1\.Rƅ\t ]ISRR2|p##xcbb,--ɩ=ž<׀*4GGG@¿cԞANLQNݻ:q8ղ ;׀ _~?BBo=ڵkM*Oټys;|>ۻTAW1pX: B"̘1P5K95..{777wh &#055򲳳!k\? @n\} 2___ 'NPٳgɭlll >7odϭ#wSSSrb1 g\ۓ䧟~]`Ydgg BWW۷ow==QFڵA4IIIApܐ􂃃 Eff%Ks=t˗)tN8ajj:rH5o⴯ !t!:_jՐ!C?YYY={tssx͚5kĉ4yk֬?~9sOKKK$HBt47dffZYY5322 q\nnnyyyHҨ/~ڸqM122(-ڦ,X 44R;ѣGL} Ѵ̨3gNbbݻg͚ di鴃C {nח9::EzjرɧOf&q!M>̙3/^/**RrssCvBѣG.] dX.p8~~~W^U155]:Çd/^$'0oOx…ݻc%ڭ:a۷o>G  211?"###""6oތ؀w=z۱c,,,>:BH"p\Ϗ[xqEE"ziU:FC#Gӧϱcp5jkk Mk֬qqq?~~~mY.؀+W>rGlqIO~mBddyxxxUU \-Nzo ۫Wȉr=+WÇg,qPJ$BhҤI'O<{qjjjpZߺ"xj=nܸ߿yZv{wSSSܹ{=w9=trrrF흘Ȇ,R8p`JJJiiiHHׯq8NϞ=#G;))%oyyԿ3g?|=h O=֖=X|y;拉=﨣͉ ;B&88:ǔ͗WJgϞ}رc:Zpy-^\\Ķg,RHMMχܡϫqh ?0--ɓt_^)?ətݻw:tLJէWJ?vؕ+WfϞ OQB(x<(?OmTH$! :رc'NOqע |3iW\7oއ~((lZ! >;v̚5k<#{:/^ܰaƍY8mJiƌs΍zZ4l SSS1eʔHj v\^)ϮMMMk00#C>H$ Mk.HѸk0X:g\\ƍY>*ZlzEGG-[;v w-M*vXt9tϟ?m4xFނD"aT:uY.\˹wl QCocЉW矹\.ٲUXc?ӆ lmmi*Z bŊ]ׯ_ojj_9Nn|IZlϦv5jԨSN6 w9TTTobbsNrhУXExۼϞ=v˥& ZXXr \P(R)B(11q„ Xk󓒒޽˶%bYq999Hnp5_Sօ˫ǏlڴIS!dllCUhhرc,X@v@ |=S#H>ɉ(ЧO?7nmyyy7n+Vh\ccA::D"Yr%dԩzzz,XA7:mҥk֬] -_w:8t tޝ0q?dqCիW#bbbpF+Wl `w%mllo׺uqF_T~8NHHtH=Tw͙3G& K*j-/^_.);;pig޽{y<ޣG@8qB!am˖-qPWWףGxSNHtYnԩS{Ic1#z-XPb޼y={;;m200ЁȌj'222BE &L@Akaȯ_ZZ6'oE_|||?M2EP{**sε]7!̴QMMц hͼ^z^VVt¢w!׿L?[om>|\?˗3OM]]3x8coҥ}opBܵtك|}}.b֭]6o {͇3744, 3fl޼YC!}%=/^3\ ŋoݺz[$%%qܐt)%:#FuӢE>} 3_ -,,v؁ ̚\kFgϝ;_ms=3F;wY >.\XRR|X:.\иA\\\ƌv-CG.gff>K5V-:uTnn.BNk:>|,/Ǝk.܅2t_ׯ_?,Zqܹsڵ n'Zݻw=<\SSZNAA R3e2١Cpt#HpUDh"kkkKKŋ744t999~5W( &M 9~t-88Xwh#Gu}̙%%%+<{ !|( HMM%bȑ/_ܻwo'_)pe˖6wIɓ'¸su>!aÆfgg.x!dmm.pBRRҒ%K߯_K۷ڵk|y}}=Q8 秦8qYYYi߽Q~bo?YPPn:uyBS1]FޘxoGڿ?ΚP(Mի{S&W(4ZZ !G?(8=:Ul?!J~K~|J@@@gt$''ԔUwʕe˖9::R3rssoݺEa,'$###$$VOO{l[o.B!:Nyy9B[nd픔dddxyy}7l{C^ۛv}}}>~Sl'D$]p!33իW۶m;p@TTMOoNSSBc*^|200 %㲲R iiiiii|rЦMhUU Dr…ׯ744޽[f 4iSUYY) &M:wwUg}×/_O!j;Ŕ`[a#?LRV" Iq\/B޽{T6ʕ+-,,z"~[4iҭ[=z~SE'jӦMB}O={_QQ1`3grP`` ڣ١RB Z# SE QΆ#?O>T堠 KKK J~CzzΝ;i*RM~iiiׯO?~x5?!VZv}y{{T$Uۗ2z蠠 ܵGC'""!J~={j]z!4}tBǎ#>Bh̘14>iҤ'OP ٶmB?D566R"EN<9o w}ɓ'4K+ ~SL<7Ay :tڴi}{l=pW H{:Ak˖-FFF(GaU}ut&LPWWיLPBG0hĈlh @#Fq9pAP(`@+,  !4bĈlr!hBhذa/.h?Bݺultq* ~?>uԼyvE"B\/;;w!B"ܹ׭[wersbmm CAS]]}ĉUV-\pEEE+oo7oB'888,]\D.*w9w\P}!tx{{CO1k׮ms&rti̡O.eB&&&xlUп\@dR/!!ؘ'&&у|3ɵI1+,,l~~~ X?+nnn2X7^_ĉ97&+FLJJd /abbafagpLQ$tɒ@{۶mV9-|VVV X[ٳ?#|7|?;kggBUX___ 7l_-Z: By|>fff^=**ի ܲe ) WX8::>| +W?ݻ˗?EM2ŋxxt0 { ?׏9|pZZڀ` xwqM]Ož*ą nQjZV՟uઢb*ֽ D@PCe>O BHn%7~3p9۷dW :.zѐ!C<<<|pSN]N7 t? "['&BHKK'AHOH!Xv@>>wss=rH aڵׯ_"CSlmmLgqQ\pB ,,,%%@ tWQQ葩SZ[[Bb#QrJt ߄SԄ֕ëg"Ə8n8P\\ bs!p3k֬KSSSM&fIII}!oW_}%Zs,ͱ0f777,++CIT|m;FݸqIGGGfǏ/m#HAu&cٲe?2:!===GfeݺuFFFx "!ϟ5k0L1qD\JNgʔ)Ǐ2:>}Bb?bKTWW󞐑`0mBXTT$G,^^^b4i$\N 7A e111="&á, /{X!˥hIMM4h$''[ZZJKPGGx ]Y`A]]ŋ{ NB>m۷8ڵk{űBܝ?~̙ⷓ$VH!&t`ԩ! 6˗/>}3fMihh?~BөD\ŋ?SUUCEzt 7+ .LNN.--~ Э[(D_ߟdU$rssutt,--l'--B}?OEzt 7SӧO/bbbzNۛvd@.ݷoϟpMMM\.~YfyF䪸ȳvڟ~Iv.\,~;&:z~s`cccRRRhnwo.֬Ycjjf|lNCC7|ӷo˗׷}ã-OMMݺ"rU\ɄUnnoӦMC19{ؙ&ࢨB$'' [md.tԾ'O .D(.@:{]...s:@7oիم|…Za XǏ| .dd2ҦLBv!@7ܹs<BGܹsdN:B={͛7kjj}&ILS{ IDATL166& f͚f\3!t͛7 HH>}Ǝ+(++{1ٳg_~kX:"11QUUU{?͞=b]vM tEbbمBp8III'O& f͚u zA(NI򪯯hdddkkKv!@ΙXZZ BG!ܼysr<'NLNNW[[ V&Lw!t_jj*Ñ0aB(55'@ȿ7o9wd#ցБpl$t*%%HBIIIqqޡŋ#G]^x ,&Lm۶W^v|бBHKKΎ*Bիd" P _`` %HjzzzC9>>Ϗ8m׮]6mz6ٵ(..B/B(>>B䄫Ç;>tBh,K~3+**222ğ=z46VG:!Իwooo?Bpvee対BqppxQCCCLJ t+444???//BtI&ijj]P8l6;??C:>dȐ( MmmmJJ [RXXX=|C:ZdӧG%&&Xӧ]PPvvv=B_rم̙3d]AAA:՝3gNdNyy /^Lv!@q 2oi'44K}2ɓdmmmmyy9rv\\\ &맓\cTUUɮ(. C[xq\\ܧO.DtϞ=[d مf``QRR·B߼yTLN1bСC.(4 2p@uuugϞ]`م PZZʷBd"Gl dqYYBN=zĈx:e݋/իٵ !t `pi_YYwߑ]!ddd;: 鱱d\.t$g``P__v!N455Ν{ak֬!KOO!TSSv!N-[VTTt ֮]GEv!N~ɍ7VZEv! BBCCϞ=[UUEv!۰aȑ#a UB|@ﯦ&.\a PSSSۅ:9rDO'oٲӓBhGYY!v!N7BCC矴4 Rnnŋ7nHv!hT*Bn :YO'o޼|҉NCXhh{ ă\~z s,F]=___MM͘ իlZfcgvx t6o޼(Cv-;w.55u߾} Zv`E.ҥK_xqm Wss?8w\GGGksu+͘1ct+**~7 K!mm !tz…CۓǏ7o 366&u:C@GWWWJN'o޼YUU.Z)##G~:ׯ: Ё+хz*992.]joo|rr[:h{:wΜ9sRiWVVfhhwKYȨРo>}СC/_L&ԬZjɒ%0R׭[Phh(m455IO.-gggUUU;;ϟ?ST˦&b&_lmؖ{فCv…Ç'@yi.PX,VBBرc̚>QnF}m߾wiĈ `٭@իW&&&| !t뛑rY,ߣY|aN͛7} N "S\\laaBG(ÇWRR7Iy޽X8@Q00E?}dnnηB9tдi:KJJ6lO?YYYItCƆo!B2d5)%ɓ鈈J 6ܑ]dڵk%5|%vSh4Zpp0Yȓϟ+++9ѩ]vظcH4tbbbܹpf.ad#Omll:@@>}455ێFR%:>|Xf͊+ &M(8ѣGΔQTGG[|(((:th:=cnn~M:λɒFI.t.\e BOB^ :.1xTr{:QQQ׮];y򤺺$?|𡬬ֶC:#}}l6=={8qHڜ9st:N={6ٵȉѣGw]\x1"czzz&M¥ALAAA5|p92#f[dooob6rӧ-q{O>Ji;Kw||-&5JB.ۣe޼ys]9|}}.g؋'Iy#ĉmfdd0n.8::u55)TjTTANNN~~~kk+I|R 77[!DFF}!dllZlB())H%Ν;Ӛ:=vر۷oR(-xDX<<>BHjjqRSS6C4pNйyҤI&R+0._u tl}||F{㰧wB =@;o߾W^mcc#!t\R__?""BB_/^oܸ!Dz€=~~~SLV t^SSsNn!;wX=*--o-Z-mAlvPP޽{ ^mۖ%VB=Zvv͛7n8bb*//'l:(iӦ;wNI3-pNիwjii]O:u9+++7 W(ׯ^:""b֬YoB`0fϞ|r# Bk.j@QN6166J%wB3f+..NYYJ򯦦fʔ)YYYzzzĉkkk322$=l0 tgXԤ]B:ȱZOO߾}[JdUuu)SJKKoݺ5h r!//A o=z_]?JffСCH:)Dž Lzybrb׮]gϞ1cƹs.KpԴ`ݻw\r˗/9B7Jnni j̙>LHH `*AEѪ\n6449lȞ?>k֬ʛ7o]PPP&&&cƌt*ڿ+W=ZYY9''GVAE$CҀb\rƌYYY2qO{:4mΜ9#ooCEFFFEE]Q@ť7ydv!F|TVVv) EGt:?dWlC\]])q!??V???kAEEEnnn+W OOO "AƎ?vXhiiYvy dWOAECh4󟖖R5jԁ<9x`R P\L&sK,qqqqqqYdL&ae455mڴՕNgff88m9so rÇڪaaa/_Ė|2,,LUUU[[;<<Ǐի{immP,o߾ TWWpuuuMMͰoJS԰0Mz@E eee==*ϯSVV z9^0p:>jԨ\:@=}4((NFFF nmmmdd!N z\zuڑ r<BȳӧSTcczک466RӧOm, !+*:@>eddL8!4hРflnn8qbff+//_ͥKƌ1bĥKl6x>1c\tIoޫW/CCØ܋E:@N옘aÆ!/]p$9s%GGGаa6pbbbLLLo.25&&!4}tA vgkkNMMuppPRR 22dFFFQ(ӧ߹sJ )#B0a;}t\m Wcc;V^˗/crHzʪ'\*ھxӧOJJJ!!!dWį8$$DIII__?""ӧOdW$] t(// RSSkaJ:aݸԴɮHZ@͛0 J+VeeeDDq ՞={uիWDDćȮH|ݸ={FvEdRɓ'شX:yűc _O555KK dggPER}||Sލ/_Μ9SGGb BHlTDnޞ7k566`k}d~?۷/J믿D655EEEƕ#Nk=ջQUUe``6d###%W"eo++\itVbb"BhРA◄]S3fLrrm ڰa˱-,,$X@ t).X܌9Sx6^K.1Dk0_-ǏB+ndb'N>|3\OOO 3f[V)..F8d:Jrvƌ#F8qk?MF@rX'Nϟ? #++S:'ꮯOJJ;wmBxzzfee1 cc۟8q7ٱ5Fa-B(88XkWX)SSSTFF.Zm 4ɓ' idd$ķ}ƍMMM%'BD7==-:\.h޽$MKK۷/B(<<ߖڒ7 VTTF:tH+B3txܹ9r$~ud؞3|hjj5j֭[\'ܹs!S @IIIXXJ>}"""%-B!_iTWWGDDGEE%,,D[ .q8nׯ_GHhc)--m+L[+t222B666_eeeٸJKKqOѣG---?rlѣG &`߿UQQ y5^-766&%%ukZL&355[˗,2>>~ %..\ׯCBBTTTtuu#""޿c|z7222Κ*ݶsssB/^YTT$~.:;;uJAIDAT{xxN722NKK*LQQ6W޽oNFW_J\vPAA6@^ú&ݻww=sY~D*څϟBׯ_'0 SؽQ2dF 8'_7. |yPP1O`B֭[NNN!Ǐ X622NURaa!a 22G'{ ݂x]r7n\VV׷ƕ'N1X)ccH)::`kk?\ |BXg#G&%%֍!4qD3'33}a``%1a]LL –!&L`0$T"UV }777nPb2tnn iMMM۷on#O:pԩƥ(ܮ0aĺ.[VTTZjd;d PX`ɓ' (.0te˖M2ٳg% 2݄Nccٳg ('''??!C|JvQLݏ_xj<)++ q8u-[TUU\~ӧE%ll;;aÆ:uJ5YrϞ=q '( =GѶlLBBvc1${:iӦh4\ZZ333}||6l؀ zvsO<9zR&M;v,NȈ=ճб^tMjjj$TNϟ?5jTuuuRRRjj E"""8κu$Q B^ 2dH~~3gx N޽|...f!. GD]yϞ=JJJwf Z[[?|@vE@>xxӧO󵴴B@$lm۶-]t͚5d P(Ǐ7668Xlٲɓ'?{%'}ݻwѣG]WA0ovvv/^Ɂ)v߾}{BB. UTTܻw/..pc1 ^ -Zɓ'&&&x5 ۷8p@[[{pc1ߧͅˮ䪫۵k9ڵkWXAvQ o \\\ L@]v555}aaaz"(s ^|8v3g"a7_eeUV^OvQ333s]xqǎ7:r-[6ugϞm߾H'Loׯ_Dd'''???[[[ltKuʕ_9s222$ `0\]]'M}x H? N/}᯾/˓VÇ'MNR FRRѣ. H0th4ɓ']\\BG$i9V\\;r>$%%]= A)++߃ >> i*B֭Qmɟ>}MC9sFszc͛6m搨EE$DztDMa|رfZr]=%iW>aaa؁^uuʁȮU<|L0̙3dW$Azzz!~Ǐ]BЉ FX!O:,`xl0l3g͛0`@nnnNN-33֭[FFF?=Q>'))iFFF!*l2;;***ƍ۽{7Bĉd@gؤ$]vU1&O.c dcO[IIIuuumw#G]tА!C.I8qbڴimblv-XNRIݻwB| م= &`00LPSSSfffۅ=ںuߍ9o޼YlYUUB1%%{=f9''gΜ9CmzKKKVVT1-,,fϞիW,\1nCɝqcW/ϟ?>566v[0w$wUƷ~>rlDIdй#| bNطo߾}.I@.A P:BA P:BA P:BA P:B9r/a@[EBBBhh(YHU (R20@A9 t B@>82̟IENDB`tins-1.1.0/examples/minsky.rb0000755000004100000410000000564212321542746016213 0ustar www-datawww-data#!/usr/bin/env ruby require 'tins' # A small Minsky (register) machine module Minsky class InterpreterError < StandardError; end class ::Proc attr_accessor :interpreter attr_accessor :name def execute interpreter.display_registers(self) call end end class Registers def initialize @registers = Hash.new(0) end def [](name) @registers[name] end def []=(name, value) @registers[name] = value end def to_s "[" + @registers.sort_by { |r,| r.to_s }.map { |r,v| "#{r}: #{v}" } * "|" + "]" end def method_missing(name, value) name = name.to_s if name[-1] == ?= name = name[0..-2].intern value >= 0 or raise InterpreterError, "only non-negative numbers can be stored in register #{name}" @registers[name] = value else super end end end class Interpreter include Tins::Interpreter extend Tins::ConstantMaker def initialize(source) @source = source @labels = [] @registers = Registers.new end attr_writer :stepping def run interpret_with_binding(@source, binding) cont = @labels.first while cont cont = cont.execute end self end def display_registers(label) @format ||= "%#{@labels.map { |l| l.name.to_s.size }.max}s" STDOUT.puts "#{@format % label.name}: #{@registers}" if @stepping STDOUT.print "? " STDOUT.flush STDIN.gets end end private def label(name, &block) @labels.find { |l| l.name == name } and raise InterpreterError, "label named '#{name}' was already defined" block.interpreter, block.name = self, name @labels << block end def register_fetch(register) @registers[register] end def register_decrement(register) @registers[register] -= 1 end def register_increment(register) @registers[register] += 1 end def label_fetch(name) label = @labels.find { |l| l.name == name } label or raise InterpreterError, "label named '#{name}' was not defined" end def increment(register, label) label = label_fetch label register_increment(register) label end def decrement(register, zero_label, else_label) register_value = register_fetch register zero_label = label_fetch zero_label else_label = label_fetch else_label if register_value.zero? zero_label else register_decrement(register) else_label end end def register @registers end def halt STDOUT.puts " *** machine halted" nil end end end if $0 == __FILE__ if ARGV.empty? Minsky::Interpreter.new(STDIN.read).run else interpreter = Minsky::Interpreter.new(File.read(ARGV.shift)) interpreter.stepping = !ARGV.empty? interpreter.run end end tins-1.1.0/examples/concatenate_compare.mtm0000644000004100000410000000222012321542746021047 0ustar www-datawww-data# vim: ts=2 sw=2 et ft=ruby # Call with four binary numbers on the tape: # $ turing.rb concatenate_compare.mtm 110 1 11 01 1. right 1, :goto => 2 2. cond 1, :if => 'B', :then => 3, :else => 1 3. right 2, :goto => 4 4. cond 2, :if => '0', :then => 7, :else => 5 5. cond 2, :if => '1', :then => 6, :else => 9 6. write 1, :symbol => '1', :goto => 8 7. write 1, :symbol => '0', :goto => 8 8. right 1, :goto => 3 9. right 3, :goto => 10 10. cond 3, :if => 'B', :then => 11, :else => 9 11. right 4, :goto => 12 12. cond 4, :if => '0', :then => 14, :else => 13 13. cond 4, :if => '1', :then => 15, :else => 17 14. write 3, :symbol => '0', :goto => 16 15. write 3, :symbol => '1', :goto => 16 16. right 3, :goto => 11 17. left 3, :goto => 18 18. left 1, :goto => 19 19. cond 3, :if => '0', :then => 20, :else => 22 20. cond 1, :if => '0', :then => 17, :else => 24 21. cond 1, :if => '1', :then => 17, :else => 24 22. cond 3, :if => '1', :then => 21, :else => 23 23. cond 1, :if => 'B', :then => 25, :else => 24 24. write 0, :symbol => '0', :goto => 26 25. write 0, :symbol => '1', :goto => 26 26. right 0, :goto => 27 27. halt tins-1.1.0/examples/ones_difference.mtm0000644000004100000410000000056512321542746020205 0ustar www-datawww-data# vim: ts=2 sw=2 et ft=ruby # Call with two strings of ones on the tape: # $ turing.rb ones_difference.mtm 1111 11 0. right 1, :goto => 1 1. right 2, :goto => 2 2. cond 1, :if => '1', :then => 3, :else => 4 3. cond 2, :if => '1', :then => 0, :else => 5 4. cond 2, :if => '1', :then => 5, :else => 7 5. write 0, :symbol => '1', :goto => 6 6. left 0, :goto => 0 7. halt tins-1.1.0/examples/bb3.png0000644000004100000410000011167412321542746015530 0ustar www-datawww-dataPNG  IHDR|4*bKGD IDATxw\3[MJ56JQQ * +ƨk&A7YM#1Xbcl[ (D myܽHٝ3|{YgyfBP ` w`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA .\x5U< t[l]B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B(B.]k.)))ѣm~,Y28UVK&9::2_.Mjj ˝5ksRPPuV~=H8:B0dRy<ޜ9sp+//۷o7₱*0DFFr\A 0G@̘1C.+p8X`322p8666`TDD A:Q!P(t `TnFI ]B0mΜ9 bݺu] @7} H&<~x `۶m;xzBB(p0܅@O˵/'AKo{:FA`Q:FA`Q:FA`Q:FA(SPP}3guUěCBBN>M_Pm%@ɓ'{I_U[[̗}=x>ضm=E `@ (Ya\4rСC{#c@&@zB t/++C 06:uWZeooqFܵA&uk,}}CY@@Q(K,A.BKLLˉ'֯_@ .;v "::֭[ԃxↆ3f.P BP.%%jhhx"3g/ݻ7k֬ VM;otl+ (cddݷmk``zԨQ&M:z(y5bĈ#G9rUC:2ꫂr9eQ "FMpy`Q:FA`Q:FA`Q:FA`Q:FA`端ںuk_P455|jsss_4k/ʕ+=zԥܽ{cƌr*̙3*׭[׭[7B(!!a{9sj-[nŊpJ_W{y.]r 233 xc( t@UWW2.%%Sݓ'O\;w޶G 2]##""$ɁI'O d2蚯Ӈѣ:V?N]p5klذaСj6ɯe2۷?v@=YyyyC 6mږ-[o- \.o߾7n܀;;ZBtJmm lM*444'Ǝf t/^=zTAݹsux/BA耎[ vvv4xORiVVVrr2%:p>,&&& 6/_y<ի: `'SPP0x]vQج[~~oVV)<`VuuuA\xАfuP(|>AMMM䇐yxx$%%Qx86x geeQzzz...'Oζiz:m%KN<9zhZt)SH$ZXamHKKDN@ P(th,,,lҤI?8P(D2p,: ӦMܹs'33ufnncn$7|'411a:vܹiӦ#Gxzz2y\@; %++룏>ZjդI>P(+BŋSN1bė_~ѡS td|>2ccc# ttWUUɓ vZܵ '''%###ܾ*Bz:: `An_uyܵ @ ]`tt}ƍ߾*0TGw@蜼ٳgϟ?kPX\\,qh[jkkLҧOw-oeee ! "22ŋ -}YWXBG[رcj* Cxz+N>vZܵP=-$J}~A~AA̙3#"">c`hϧ]|ygʔ)Bp͸Kk:Z~xR4))O>/))|* /BGH$#GHRPSSSIIIII'|B>b3@PTTP(Ytd2LwEGGd2uH ={ w!^:fmvWWW3_R'X:BG;v\.?+$O͵V?nN Yf}gY<z:Zn$kݻw r{}aÆa`.xYjjjk+>;w?ql=Am6wwwUu@ ~:*=C{x;w}ւUl̬[np[Gk)@' 8k?nkk<66UKEEEmmszںuj4jAٚU() thaCCׯ5 !iӦNhזFFFAAAoUl 6b:;r}||lmmcccB4z5Qڷ O͵v9n8k777B F t6BGAnРA\.!rkV߸q#5Qڷ) ) v- .\iii|?tМ"|]"r9 J:Ϗݳg /W(K,AR]e|$r| \ai%444\2 @Fbbb\\\N8~z k%o!diiijj CD"ʕ+B BFwADtt[MKV:Lضmٳg7 rɑ,* ZxqCCÌ3ꨭSMM thx\ \ f͚6_pE3g466^dݻwo֬Ys"6mv,奭 th7uT2,8Ό3 6_k``3jԨ0"ȑ#NNNTey]Kyi+˜vxRedPP\.W,9̺5@PZZ*Jyyw!J:`,^OOnh^z:ZB >:੹} tWo[Wh"j@"<w!2:?}tB LLLpV>dҽ/RYYzjZ҂rrvrppr?@TZZ: >Ro,a9\.KIGKA0- e2X,Rf!h:y{{7 ~qY`a8p`@7K`)/MᆱG~p<=='M$ 5Ea Nޒ4@ (** *ߟLhxx84P(lhhx)B t0puuEzj\%aZvvvvvvPPB2""wEޞýdÜc\r!m``. r!t4N:XVVo߾}IRБ#GOixj th$Jwݷo߱cǚݼy3<<<<<޽{iiicƌ۷ݻO5-ׯ_>wܞ={'%%X+gذaIII/^ٳܹsׯ____f 5P6&&G\.7""͛y͛7#""\n=bbbjkkSرw@E:VVV|>?***??-EEE|+++X\YYIGZ 55!s܅U@PL$DǏǏE"H$*//Nz*B* tR\\,bӧOjӧbX$Sղhllr]P>>wdKc@ ]2VbTeOO9s8;;edd5 w]m5jԥKҜ̙e]`i0wYD" B BCC_~zhh(AB066V"ஈFuuuA=zw! t Z,x[nuGm۶mƌU i]t-rX,iQ;ҼܹC߁lmmׯ_O_&: S"H S$//Юv%ə3gW|hΝ666WB/ƕwUUUEGG#|||;СC>9aH$ߦjW_uiD"###rWYY vh͚5r\Pz !dmmM߱O>uT4)**׷Ϟ=eBԢgϞb rOQQ%ͶI٥z;g}6p@4ѭɉݻwcT?lذ.!jFUWWXZZ oi̙\v?leeE!t%t9}ӧO˔WHNrppp8׮] b䛊hhh W^>ΥK pwwB˫<<55!'P۸ҝ;wB> tə0aA={_>tjjjrrr֯_okkkaaNCSWWyfr\ĉ)_7c!jUA?~M9t>3CfHՍ/R~OmΟ?occJ6׽{͛7>6OoA``2+!t}P( $ jANӧ6`i"mrV+W¼4bVdvv6ݔ#w LKK# |.˗B-`,Ŝ4򎲋Kll,x$Irrr~~~mܹs RӧO<(ؿ?*XqZZ+ WW)S<|077XA,_חt(tH7n &9;;S8+4 |)SΟ?OIaXgggr7l onҥFFFܴiL&@.MvlsCsNDDdz/_]]^|)ɹZѣA.t@$EGGWTTஈJfff"wEԻqB6,::'ODGGDD95::ɓ'+˗/BO]<\,w֍a*77wE%w֭X,օwͷlق :oxyoy}uֽ{ȹvvv3#W]mSSe˖gϞӧτ pr}={~]l)BhfPK IDAT6/[,??Ν>D(Yݵ֬Y# k%$$丸 2d˖-B8;;COG(%i\S媵S^^.LMM [OJbDDDh]2vعst>}*̌:X$O7-,,|||=zDE?1b*@gAPehhHΥxa^x!>|د_ݻ:u5ط~₻ Y:8qA+W#Gܻwݽ{744WMM {,۷oϗJ CcǾ{ >..ɉʕ+/dff999ũvj\\u:ud@!ݿ G*"H6l@Fϔ)SLp7lؠഴ4;;;77[nٔ*--Eѱ3,Ya{ݻ)kӧ#F044ܹs'Umj\n``g܅NQ]LLL֮]p1MMM(ZNf'ww wS`p v܉?>x111{GY^^px\s C%\iӦH ,̘1#+++55K X@h*?~ѣG˖-(ěZ^zeff~}lA tnܸq /&$$|WW9sfmm-P($.t BkZmo۷E"B4:hР㮈^ӧ С͛===Ǎyw}}}> B:Ԩܽ{EضçMrJL"Z888| tc7o<܅A__?..n׮]6l=zgpWD=.=:mKLiӦ9syYǏ4ʕ+ˡ<5:HJJ*..^t)B:s޽{nݺw9 46l0fwww܅t{'OFFFᮈ2:uٳgQ"'&&;vlذaZ;:ڴiS^>܅t\"J tiP@(~w!:jسgϒ%K3233'N8nܸ5kr6:jٶmޜ9sp";vl޼o d\5 tT'J7op&.?=͛7oԨQ ^HHHfffEEŠA]4, tTӽ{~G ˗4hA@PUUU]]Ul۶$22w!4255=xڵk͚5K#$AtYSSw-"bٲe)))gΜ]QA:,eӧOIygeee 0ȑ#i a9.۸qĉɞptt %NlܸqРAÇ]{EEE߼yԜ t:VZZ;T6hР,r*z:,ӱ8KK3f.DXYYZ~B t:P__믿.X@__w-=zFz z : BZhB4ĉ\B.?x%&- Eqq1Bxeiiу޷o9vSN]  drKy)X = &333AGedd.JX>O.?A̶ṉ@WAO r!P(*++wMW_}'UeAf:on.MMM ӣG4hPbb"4Z``rG}86yCeeeJRЍ72 .,Zhʔ)t/?` AIIIDf~ƍ'LK`:\.f4k֬ Z3.yCee%τ$$$t~wUUU 0`…/d2YiizeZ@輡kX͛CBBԣ5k,X@B1c͛7lr)':wm濺m;vС/"99Y.s89s樼Ja'] +W̟??>>5˗/ϧ83^n;vlFFF]]kL/_\zjm\XXι`ȼgώ5 !dooOP(ܼys]]̙rB\.722R.cV\vM__A TkpРANNNkNT*߿?B/99YPD"ݻ⊊ BnCCuׯ===[MxoCn nfaaH$222211D!___D`s\ru\V@Ǵ6t$Ill@ "44gbAfffٌ >vZP\GEEQ@0tb Nj}v'_X]]b KKK>Ckt??? Z_aYm_S\t5*t***bq D"ѣGThױ'888++:AkcǎWp87onp5NiiH$211122Dj6NDppK(tqqqAx<q##bkͧSTToaa!={Fa㍍B( 11Arss>}WX>εй~DDϷ}MdlODä{-Y\ѱGp5FNVVVpp0qpp}53MKK{BJW5?}k-as%rH{||<{iiiBFkpƄNbbb@@Bw9xL&[ύ7"""8@ s:r>>>'&&b6w툈gcc#pW\9_~#G<="EGGԞsS:... 6{IttrjOii)4kĮ!'8;;s܈7nந˞?"E}}=NYl /_bkkkr͝;wBAAAHHۺu:?dCCCwwsfffv ҫWbccmmmɩ=W6G 84&Ċh333rMAA <ֶ)66H$gΜ!_˺;wp8]zHGGGrjիWUn/^ %k\ӧB%%%I4O},,,._LGiii#GDDa&Mj~㣏>bx"h= Ça:IOO'=<<D_®~Q+wޥH9 X*dEEE۷o'ׅ@mܸ;mh: "44t޽zpD{g&u֭ 333SByjjjrrr֯_okkkaaNCoHKK;v,yC–'Nzw(lm\ws}U')Cf{ B.zW\INTH$:tPUUH$IR [=B(??f纫(9+WoZv [^^^TTdz􍎍0arŋm?ZU9fС4k@ 6n}k1W\AAH$244455DԶuVwwwrL&ۺuw_T#z.L.tO8JNNFZCZs!1]ӧObH$Fzz^kΝ;G@*>}>J理Bbcc{IoygXXXAAjkk8P\3pi9S[nzzzo-#8NO_PPPm5SL9)уxMZnmʕzzzz/n sNjjjbcc8Nhh(,qVVV|>?***//wEJs>..ɉ)d_*//D"Us l됧'B( %%wEj)..Dbӧ+b8:-C" 8w:r~X,ң\Zg+tHr<11!)ݽ{744HAl %C}cU233i5NNNqqq+oee%++++DN!kOMs[aC ȩ=eee | -B06T<~4.ϵƥ)4,td2ٚ5k\nhhh^^X,677'TCP($"44r|̘1\.Rƅ\t ]ISRR2|p##xcbb,--ɩ=ž<׀*4GGG@¿cԞANLQNݻ:q8ղ ;׀ _~?BBo=ڵkM*Oټys;|>ۻTAW1pX: B"̘1P5K95..{777wh &#055򲳳!k\? @n\} 2___ 'NPٳgɭlll >7odϭ#wSSSrb1 g\ۓ䧟~]`Ydgg BWW۷ow==QFڵA4IIIApܐ􂃃 Eff%Ks=t˗)tN8ajj:rH5o⴯ !t!:_jՐ!C?YYY={tssx͚5kĉ4yk֬?~9sOKKK$HBt47dffZYY5322 q\nnnyyyHҨ/~ڸqM122(-ڦ,X 44R;ѣGL} Ѵ̨3gNbbݻg͚ di鴃C {nח9::EzjرɧOf&q!M>̙3/^/**RrssCvBѣG.] dX.p8~~~W^U155]:Çd/^$'0oOx…ݻc%ڭ:a۷o>G  211?"###""6oތ؀w=z۱c,,,>:BH"p\Ϗ[xqEE"ziU:FC#Gӧϱcp5jkk Mk֬qqq?~~~mY.؀+W>rGlqIO~mBddyxxxUU \-Nzo ۫Wȉr=+WÇg,qPJ$BhҤI'O<{qjjjpZߺ"xj=nܸ߿yZv{wSSSܹ{=w9=trrrF흘Ȇ,R8p`JJJiiiHHׯq8NϞ=#G;))%oyyԿ3g?|=h O=֖=X|y;拉=﨣͉ ;B&88:ǔ͗WJgϞ}رc:Zpy-^\\Ķg,RHMMχܡϫqh ?0--ɓt_^)?ətݻw:tLJէWJ?vؕ+WfϞ OQB(x<(?OmTH$! :رc'NOqע |3iW\7oއ~((lZ! >;v̚5k<#{:/^ܰaƍY8mJiƌs΍zZ4l SSS1eʔHj v\^)ϮMMMk00#C>H$ Mk.HѸk0X:g\\ƍY>*ZlzEGG-[;v w-M*vXt9tϟ?m4xFނD"aT:uY.\˹wl QCocЉW矹\.ٲUXc?ӆ lmmi*Z bŊ]ׯ_ojj_9Nn|IZlϦv5jԨSN6 w9TTTobbsNrhУXExۼϞ=v˥& ZXXr \P(R)B(11q„ Xk󓒒޽˶%bYq999Hnp5_Sօ˫ǏlڴIS!dllCUhhرc,X@v@ |=S#H>ɉ(ЧO?7nmyyy7n+Vh\ccA::D"Yr%dԩzzz,XA7:mҥk֬] -_w:8t tޝ0q?dqCիW#bbbpF+Wl `w%mllo׺uqF_T~8NHHtH=Tw͙3G& K*j-/^_.);;pig޽{y<ޣG@8qB!am˖-qPWWףGxSNHtYnԩS{Ic1#z-XPb޼y={;;m200ЁȌj'222BE &L@Akaȯ_ZZ6'oE_|||?M2EP{**sε]7!̴QMMц hͼ^z^VVt¢w!׿L?[om>|\?˗3OM]]3x8coҥ}opBܵtك|}}.b֭]6o {͇3744, 3fl޼YC!}%=/^3\ ŋoݺz[$%%qܐt)%:#FuӢE>} 3_ -,,v؁ ̚\kFgϝ;_ms=3F;wY >.\XRR|X:.\иA\\\ƌv-CG.gff>K5V-:uTnn.BNk:>|,/Ǝk.܅2t_ׯ_?,Zqܹsڵ n'Zݻw=<\SSZNAA R3e2١Cpt#HpUDh"kkkKKŋ744t999~5W( &M 9~t-88Xwh#Gu}̙%%%+<{ !|( HMM%bȑ/_ܻwo'_)pe˖6wIɓ'¸su>!aÆfgg.x!dmm.pBRRҒ%K߯_K۷ڵk|y}}=Q8 秦8qYYYi߽Q~bo?YPPn:uyBS1]FޘxoGڿ?ΚP(Mի{S&W(4ZZ !G?(8=:Ul?!J~K~|J@@@gt$''ԔUwʕe˖9::R3rssoݺEa,'$###$$VOO{l[o.B!:Nyy9B[nd픔dddxyy}7l{C^ۛv}}}>~Sl'D$]p!33իW۶m;p@TTMOoNSSBc*^|200 %㲲R iiiiii|rЦMhUU Dr…ׯ744޽[f 4iSUYY) &M:wwUg}×/_O!j;Ŕ`[a#?LRV" Iq\/B޽{T6ʕ+-,,z"~[4iҭ[=z~SE'jӦMB}O={_QQ1`3grP`` ڣ١RB Z# SE QΆ#?O>T堠 KKK J~CzzΝ;i*RM~iiiׯO?~x5?!VZv}y{{T$Uۗ2z蠠 ܵGC'""!J~={j]z!4}tBǎ#>Bh̘14>iҤ'OP ٶmB?D566R"EN<9o w}ɓ'4K+ ~SL<7Ay :tڴi}{l=pW H{:Ak˖-FFF(GaU}ut&LPWWיLPBG0hĈlh @#Fq9pAP(`@+,  !4bĈlr!hBhذa/.h?Bݺultq* ~?>uԼyvE"B\/;;w!B"ܹ׭[wersbmm CAS]]}ĉUV-\pEEE+oo7oB'888,]\D.*w9w\P}!tx{{CO1k׮ms&rti̡O.eB&&&xlUп\@dR/!!ؘ'&&у|3ɵI1+,,l~~~ X?+nnn2X7^_ĉ97&+FLJJd /abbafagpLQ$tɒ@{۶mV9-|VVV X[ٳ?#|7|?;kggBUX___ 7l_-Z: By|>fff^=**ի ܲe ) WX8::>| +W?ݻ˗?EM2ŋxxt0 { ?׏9|pZZڀ` xwqM]Ož*ą nQjZV՟uઢb*ֽ D@PCe>O BHn%7~3p9۷dW :.zѐ!C<<<|pSN]N7 t? "['&BHKK'AHOH!Xv@>>wss=rH aڵׯ_"CSlmmLgqQ\pB ,,,%%@ tWQQ葩SZ[[Bb#QrJt ߄SԄ֕ëg"Ə8n8P\\ bs!p3k֬KSSSM&fIII}!oW_}%Zs,ͱ0f777,++CIT|m;FݸqIGGGfǏ/m#HAu&cٲe?2:!===GfeݺuFFFx "!ϟ5k0L1qD\JNgʔ)Ǐ2:>}Bb?bKTWW󞐑`0mBXTT$G,^^^b4i$\N 7A e111="&á, /{X!˥hIMM4h$''[ZZJKPGGx ]Y`A]]ŋ{ NB>m۷8ڵk{űBܝ?~̙ⷓ$VH!&t`ԩ! 6˗/>}3fMihh?~BөD\ŋ?SUUCEzt 7+ .LNN.--~ Э[(D_ߟdU$rssutt,--l'--B}?OEzt 7SӧO/bbbzNۛvd@.ݷoϟpMMM\.~YfyF䪸ȳvڟ~Iv.\,~;&:z~s`cccRRRhnwo.֬Ycjjf|lNCC7|ӷo˗׷}ã-OMMݺ"rU\ɄUnnoӦMC19{ؙ&ࢨB$'' [md.tԾ'O .D(.@:{]...s:@7oիم|…Za XǏ| .dd2ҦLBv!@7ܹs<BGܹsdN:B={͛7kjj}&ILS{ IDATL166& f͚f\3!t͛7 HH>}Ǝ+(++{1ٳg_~kX:"11QUUU{?͞=b]vM tEbbمBp8III'O& f͚u zA(NI򪯯hdddkkKv!@ΙXZZ BG!ܼysr<'NLNNW[[ V&Lw!t_jj*Ñ0aB(55'@ȿ7o9wd#ցБpl$t*%%HBIIIqqޡŋ#G]^x ,&Lm۶W^v|бBHKKΎ*Bիd" P _`` %HjzzzC9>>Ϗ8m׮]6mz6ٵ(..B/B(>>B䄫Ç;>tBh,K~3+**222ğ=z46VG:!Իwooo?Bpvee対BqppxQCCCLJ t+444???//BtI&ijj]P8l6;??C:>dȐ( MmmmJJ [RXXX=|C:ZdӧG%&&Xӧ]PPvvv=B_rم̙3d]AAA:՝3gNdNyy /^Lv!@q 2oi'44K}2ɓdmmmmyy9rv\\\ &맓\cTUUɮ(. C[xq\\ܧO.DtϞ=[d مf``QRR·B߼yTLN1bСC.(4 2p@uuugϞ]`م PZZʷBd"Gl dqYYBN=zĈx:e݋/իٵ !t `pi_YYwߑ]!ddd;: 鱱d\.t$g``P__v!N455Ν{ak֬!KOO!TSSv!N-[VTTt ֮]GEv!N~ɍ7VZEv! BBCCϞ=[UUEv!۰aȑ#a UB|@ﯦ&.\a PSSSۅ:9rDO'oٲӓBhGYY!v!N7BCC矴4 Rnnŋ7nHv!hT*Bn :YO'o޼|҉NCXhh{ ă\~z s,F]=___MM͘ իlZfcgvx t6o޼(Cv-;w.55u߾} Zv`E.ҥK_xqm Wss?8w\GGGksu+͘1ct+**~7 K!mm !tz…CۓǏ7o 366&u:C@GWWWJN'o޼YUU.Z)##G~:ׯ: Ё+хz*992.]joo|rr[:h{:wΜ9sRiWVVfhhwKYȨРo>}СC/_L&ԬZjɒ%0R׭[Phh(m455IO.-gggUUU;;ϟ?ST˦&b&_lmؖ{فCv…Ç'@yi.PX,VBBرc̚>QnF}m߾wiĈ `٭@իW&&&| !t뛑rY,ߣY|aN͛7} N "S\\laaBG(ÇWRR7Iy޽X8@Q00E?}dnnηB9tдi:KJJ6lO?YYYItCƆo!B2d5)%ɓ鈈J 6ܑ]dڵk%5|%vSh4Zpp0Yȓϟ+++9ѩ]vظcH4tbbbܹpf.ad#Omll:@@>}455ێFR%:>|Xf͊+ &M(8ѣGΔQTGG[|(((:th:=cnn~M:λɒFI.t.\e BOB^ :.1xTr{:QQQ׮];y򤺺$?|𡬬ֶC:#}}l6=={8qHڜ9st:N={6ٵȉѣGw]\x1"czzz&M¥ALAAA5|p92#f[dooob6rӧ-q{O>Ji;Kw||-&5JB.ۣe޼ys]9|}}.g؋'Iy#ĉmfdd0n.8::u55)TjTTANNN~~~kk+I|R 77[!DFF}!dllZlB())H%Ν;Ӛ:=vر۷oR(-xDX<<>BHjjqRSS6C4pNйyҤI&R+0._u tl}||F{㰧wB =@;o߾W^mcc#!t\R__?""BB_/^oܸ!Dz€=~~~SLV t^SSsNn!;wX=*--o-Z-mAlvPP޽{ ^mۖ%VB=Zvv͛7n8bb*//'l:(iӦ;wNI3-pNիwjii]O:u9+++7 W(ׯ^:""b֬YoB`0fϞ|r# Bk.j@QN6166J%wB3f+..NYYJ򯦦fʔ)YYYzzzĉkkk322$=l0 tgXԤ]B:ȱZOO߾}[JdUuu)SJKKoݺ5h r!//A o=z_]?JffСCH:)Dž Lzybrb׮]gϞ1cƹs.KpԴ`ݻw\r˗/9B7Jnni j̙>LHH `*AEѪ\n6449lȞ?>k֬ʛ7o]PPP&&&cƌt*ڿ+W=ZYY9''GVAE$CҀb\rƌYYY2qO{:4mΜ9#ooCEFFFEE]Q@ť7ydv!F|TVVv) EGt:?dWlC\]])q!??V???kAEEEnnn+W OOO "AƎ?vXhiiYvy dWOAECh4󟖖R5jԁ<9x`R P\L&sK,qqqqqqYdL&ae455mڴՕNgff88m9so rÇڪaaa/_Ė|2,,LUUU[[;<<Ǐի{immP,o߾ TWWpuuuMMͰoJS԰0Mz@E eee==*ϯSVV z9^0p:>jԨ\:@=}4((NFFF nmmmdd!N z\zuڑ r<BȳӧSTcczک466RӧOm, !+*:@>eddL8!4hРflnn8qbff+//_ͥKƌ1bĥKl6x>1c\tIoޫW/CCØ܋E:@N옘aÆ!/]p$9s%GGGаa6pbbbLLLo.25&&!4}tA vgkkNMMuppPRR 22dFFFQ(ӧ߹sJ )#B0a;}t\m Wcc;V^˗/crHzʪ'\*ھxӧOJJJ!!!dWį8$$DIII__?""ӧOdW$] t(// RSSkaJ:aݸԴɮHZ@͛0 J+VeeeDDq ՞={uիWDDćȮH|ݸ={FvEdRɓ'شX:yűc _O555KK dggPER}||Sލ/_Μ9SGGb BHlTDnޞ7k566`k}d~?۷/J믿D655EEEƕ#Nk=ջQUUe``6d###%W"eo++\itVbb"BhРA◄]S3fLrrm ڰa˱-,,$X@ t).X܌9Sx6^K.1Dk0_-ǏB+ndb'N>|3\OOO 3f[V)..F8d:Jrvƌ#F8qk?MF@rX'Nϟ? #++S:'ꮯOJJ;wmBxzzfee1 cc۟8q7ٱ5Fa-B(88XkWX)SSSTFF.Zm 4ɓ' idd$ķ}ƍMMM%'BD7==-:\.h޽$MKK۷/B(<<ߖڒ7 VTTF:tH+B3txܹ9r$~ud؞3|hjj5j֭[\'ܹs!S @IIIXXJ>}"""%-B!_iTWWGDDGEE%,,D[ .q8nׯ_GHhc)--m+L[+t222B666_eeeٸJKKqOѣG---?rlѣG &`߿UQQ y5^-766&%%ukZL&355[˗,2>>~ %..\ׯCBBTTTtuu#""޿c|z7222Κ*ݶsssB/^YTT$~.:;;uJAIDAT{xxN722NKK*LQQ6W޽oNFW_J\vPAA6@^ú&ݻww=sY~D*څϟBׯ_'0 SؽQ2dF 8'_7. |yPP1O`B֭[NNN!Ǐ X622NURaa!a 22G'{ ݂x]r7n\VV׷ƕ'N1X)ccH)::`kk?\ |BXg#G&%%֍!4qD3'33}a``%1a]LL –!&L`0$T"UV }777nPb2tnn iMMM۷on#O:pԩƥ(ܮ0aĺ.[VTTZjd;d PX`ɓ' (.0te˖M2ٳg% 2݄Nccٳg ('''??!C|JvQLݏ_xj<)++ q8u-[TUU\~ӧE%ll;;aÆ:uJ5YrϞ=q '( =GѶlLBBvc1${:iӦh4\ZZ333}||6l؀ zvsO<9zR&M;v,NȈ=ճб^tMjjj$TNϟ?5jTuuuRRRjj E"""8κu$Q B^ 2dH~~3gx N޽|...f!. GD]yϞ=JJJwf Z[[?|@vE@>xxӧO󵴴B@$lm۶-]t͚5d P(Ǐ7668Xlٲɓ'?{%'}ݻwѣG]WA0ovvv/^Ɂ)v߾}{BB. UTTܻw/..pc1 ^ -Zɓ'&&&x5 ۷8p@[[{pc1ߧͅˮ䪫۵k9ڵkWXAvQ o \\\ L@]v555}aaaz"(s ^|8v3g"a7_eeUV^OvQ333s]xqǎ7:r-[6ugϞm߾H'Loׯ_Dd'''???[[[ltKuʕ_9s222$ `0\]]'M}x H? N/}᯾/˓VÇ'MNR FRRѣ. H0th4ɓ']\\BG$i9V\\;r>$%%]= A)++߃ >> i*B֭Qmɟ>}MC9sFszc͛6m搨EE$DztDMa|رfZr]=%iW>aaa؁^uuʁȮU<|L0̙3dW$Azzz!~Ǐ]BЉ FX!O:,`xl0l3g͛0`@nnnNN-33֭[FFF?=Q>'))iFFF!*l2;;***ƍ۽{7Bĉd@gؤ$]vU1&O.c dcO[IIIuuumw#G]tА!C.I8qbڴimblv-XNRIݻwB| م= &`00LPSSSfffۅ=ںuߍ9o޼YlYUUB1%%{=f9''gΜ9CmzKKKVVT1-,,fϞիW,\1nCɝqcW/ϟ?>566v[0w$wUƷ~>rlDIdй#| bNطo߾}.I@.A P:BA P:BA P:BA P:B9r/a@[EBBBhh(YHU (R20@A9 t B@>82̟IENDB`tins-1.1.0/examples/bb3.stm0000644000004100000410000000121312321542746015532 0ustar www-datawww-data# vim: ts=2 sw=2 et ft=ruby # Call with an empty tape # $ turing.rb bb3.stm '' # Busy Beaver: 3-state, 2-symbol # state A 1. cond :if => 'B', :then => 2, :else => 4 2. write :symbol => '1', :goto => 3 3. right :goto => 6 4. write :symbol => '1', :goto => 5 5. right :goto => 16 # state B 6. cond :if => 'B', :then => 7, :else => 9 7. write :symbol => 'B', :goto => 8 8. right :goto => 11 9. write :symbol => '1', :goto => 10 10. right :goto => 6 # state C 11. cond :if => 'B', :then => 12, :else => 14 12. write :symbol => '1', :goto => 13 13. left :goto => 11 14. write :symbol => '1', :goto => 15 15. left :goto => 1 # halt 16. halt tins-1.1.0/examples/recipe2.rb0000755000004100000410000000333512321542746016227 0ustar www-datawww-data#!/usr/bin/env ruby require 'tins/xt' $:.unshift 'examples' require 'recipe_common' class Cup < Unit; end class Teaspoon < Unit; end class Tablespoon < Unit; end class Flour < Ingredient; end class Bakingpowder < Ingredient; end class Salt < Ingredient; end class Egg < Ingredient; end class Milk < Ingredient; end class Butter < Ingredient; end class Recipe < Tins::BlankSlate.with(:respond_to?, :instance_exec, :inspect, /^deflect/) include Tins::Deflect def initialize(&block) @ingredients = [] deflector = Deflector.new do |number, id, name| if unit = Unit.unit(name, number) unit else ingredient = Ingredient.ingredient(name, number) @ingredients << ingredient end end deflect_start(Numeric, :method_missing, deflector) deflector2 = Deflector.new do |unit, id, name| ingredient = Ingredient.ingredient(name, unit) @ingredients << ingredient end deflect_start(Unit, :method_missing, deflector2) instance_exec(&block) ensure deflect_stop(Numeric, :method_missing) if deflect?(Numeric, :method_missing) deflect_stop(Unit, :method_missing) if deflect?(Unit, :method_missing) end attr_reader :ingredients def to_a @ingredients end alias to_ary to_a def to_s to_a * "\n" end end class RecipeInterpreter def recipe(&block) Recipe.new(&block) end end recipe_source = <M_Pm%@ɓ'{I_U[[̗}=x>ضm=E `@ (Ya\4rСC{#c@&@zB t/++C 06:uWZeooqFܵA&uk,}}CY@@Q(K,A.BKLLˉ'֯_@ .;v "::֭[ԃxↆ3f.P BP.%%jhhx"3g/ݻ7k֬ VM;otl+ (cddݷmk``zԨQ&M:z(y5bĈ#G9rUC:2ꫂr9eQ "FMpy`Q:FA`Q:FA`Q:FA`Q:FA`端ںuk_P455|jsss_4k/ʕ+=zԥܽ{cƌr*̙3*׭[׭[7B(!!a{9sj-[nŊpJ_W{y.]r 233 xc( t@UWW2.%%Sݓ'O\;w޶G 2]##""$ɁI'O d2蚯Ӈѣ:V?N]p5klذaСj6ɯe2۷?v@=YyyyC 6mږ-[o- \.o߾7n܀;;ZBtJmm lM*444'Ǝf t/^=zTAݹsux/BA耎[ vvv4xORiVVVrr2%:p>,&&& 6/_y<ի: `'SPP0x]vQج[~~oVV)<`VuuuA\xАfuP(|>AMMM䇐yxx$%%Qx86x geeQzzz...'Oζiz:m%KN<9zhZt)SH$ZXamHKKDN@ P(th,,,lҤI?8P(D2p,: ӦMܹs'33ufnncn$7|'411a:vܹiӦ#Gxzz2y\@; %++룏>ZjդI>P(+BŋSN1bė_~ѡS td|>2ccc# ttWUUɓ vZܵ '''%###ܾ*Bz:: `An_uyܵ @ ]`tt}ƍ߾*0TGw@蜼ٳgϟ?kPX\\,qh[jkkLҧOw-oeee ! "22ŋ -}YWXBG[رcj* Cxz+N>vZܵP=-$J}~A~AA̙3#"">c`hϧ]|ygʔ)Bp͸Kk:Z~xR4))O>/))|* /BGH$#GHRPSSSIIIII'|B>b3@PTTP(Ytd2LwEGGd2uH ={ w!^:fmvWWW3_R'X:BG;v\.?+$O͵V?nN Yf}gY<z:Zn$kݻw r{}aÆa`.xYjjjk+>;w?ql=Am6wwwUu@ ~:*=C{x;w}ւUl̬[np[Gk)@' 8k?nkk<66UKEEEmmszںuj4jAٚU() thaCCׯ5 !iӦNhזFFFAAAoUl 6b:;r}||lmmcccB4z5Qڷ O͵v9n8k777B F t6BGAnРA\.!rkV߸q#5Qڷ) ) v- .\iii|?tМ"|]"r9 J:Ϗݳg /W(K,AR]e|$r| \ai%444\2 @Fbbb\\\N8~z k%o!diiijj CD"ʕ+B BFwADtt[MKV:Lضmٳg7 rɑ,* ZxqCCÌ3ꨭSMM thx\ \ f͚6_pE3g466^dݻwo֬Ys"6mv,奭 th7uT2,8Ό3 6_k``3jԨ0"ȑ#NNNTey]Kyi+˜vxRedPP\.W,9̺5@PZZ*Jyyw!J:`,^OOnh^z:ZB >:੹} tWo[Wh"j@"<w!2:?}tB LLLpV>dҽ/RYYzjZ҂rrvrppr?@TZZ: >Ro,a9\.KIGKA0- e2X,Rf!h:y{{7 ~qY`a8p`@7K`)/MᆱG~p<=='M$ 5Ea Nޒ4@ (** *ߟLhxx84P(lhhx)B t0puuEzj\%aZvvvvvvPPB2""wEޞýdÜc\r!m``. r!t4N:XVVo߾}IRБ#GOixj th$Jwݷo߱cǚݼy3<<<<<޽{iiicƌ۷ݻO5-ׯ_>wܞ={'%%X+gذaIII/^ٳܹsׯ____f 5P6&&G\.7""͛y͛7#""\n=bbbjkkSرw@E:VVV|>?***??-EEE|+++X\YYIGZ 55!s܅U@PL$DǏǏE"H$*//Nz*B* tR\\,bӧOjӧbX$Sղhllr]P>>wdKc@ ]2VbTeOO9s8;;edd5 w]m5jԥKҜ̙e]`i0wYD" B BCC_~zhh(AB066V"ஈFuuuA=zw! t Z,x[nuGm۶mƌU i]t-rX,iQ;ҼܹC߁lmmׯ_O_&: S"H S$//Юv%ə3gW|hΝ666WB/ƕwUUUEGG#|||;СC>9aH$ߦjW_uiD"###rWYY vh͚5r\Pz !dmmM߱O>uT4)**׷Ϟ=eBԢgϞb rOQQ%ͶI٥z;g}6p@4ѭɉݻwcT?lذ.!jFUWWXZZ oi̙\v?leeE!t%t9}ӧO˔WHNrppp8׮] b䛊hhh W^>ΥK pwwB˫<<55!'P۸ҝ;wB> tə0aA={_>tjjjrrr֯_okkkaaNCSWWyfr\ĉ)_7c!jUA?~M9t>3CfHՍ/R~OmΟ?occJ6׽{͛7>6OoA``2+!t}P( $ jANӧ6`i"mrV+W¼4bVdvv6ݔ#w LKK# |.˗B-`,Ŝ4򎲋Kll,x$Irrr~~~mܹs RӧO<(ؿ?*XqZZ+ WW)S<|077XA,_חt(tH7n &9;;S8+4 |)SΟ?OIaXgggr7l onҥFFFܴiL&@.MvlsCsNDDdz/_]]^|)ɹZѣA.t@$EGGWTTஈJfff"wEԻqB6,::'ODGGDD95::ɓ'+˗/BO]<\,w֍a*77wE%w֭X,օwͷlق :oxyoy}uֽ{ȹvvv3#W]mSSe˖gϞӧτ pr}={~]l)BhfPK IDAT6/[,??Ν>D(Yݵ֬Y# k%$$丸 2d˖-B8;;COG(%i\S媵S^^.LMM [OJbDDDh]2vعst>}*̌:X$O7-,,|||=zDE?1b*@gAPehhHΥxa^x!>|د_ݻ:u5ط~₻ Y:8qA+W#Gܻwݽ{744WMM {,۷oϗJ CcǾ{ >..ɉʕ+/dff999ũvj\\u:ud@!ݿ G*"H6l@Fϔ)SLp7lؠഴ4;;;77[nٔ*--Eѱ3,Ya{ݻ)kӧ#F044ܹs'Umj\n``g܅NQ]LLL֮]p1MMM(ZNf'ww wS`p v܉?>x111{GY^^px\s C%\iӦH ,̘1#+++55K X@h*?~ѣG˖-(ěZ^zeff~}lA tnܸq /&$$|WW9sfmm-P($.t BkZmo۷E"B4:hР㮈^ӧ С͛===Ǎyw}}}> B:Ԩܽ{EضçMrJL"Z888| tc7o<܅A__?..n׮]6l=zgpWD=.=:mKLiӦ9syYǏ4ʕ+ˡ<5:HJJ*..^t)B:s޽{nݺw9 46l0fwww܅t{'OFFFᮈ2:uٳgQ"'&&;vlذaZ;:ڴiS^>܅t\"J tiP@(~w!:jسgϒ%K3233'N8nܸ5kr6:jٶmޜ9sp";vl޼o d\5 tT'J7op&.?=͛7oԨQ ^HHHfffEEŠA]4, tTӽ{~G ˗4hA@PUUU]]Ul۶$22w!4255=xڵk͚5K#$AtYSSw-"bٲe)))gΜ]QA:,eӧOIygeee 0ȑ#i a9.۸qĉɞptt %NlܸqРAÇ]{EEE߼yԜ t:VZZ;T6hР,r*z:,ӱ8KK3f.DXYYZ~B t:P__믿.X@__w-=zFz z : BZhB4ĉ\B.?x%&- Eqq1Bxeiiу޷o9vSN]  drKy)X = &333AGedd.JX>O.?A̶ṉ@WAO r!P(*++wMW_}'UeAf:on.MMM ӣG4hPbb"4Z``rG}86yCeeeJRЍ72 .,Zhʔ)t/?` AIIIDf~ƍ'LK`:\.f4k֬ Z3.yCee%τ$$$t~wUUU 0`…/d2YiizeZ@輡kX͛CBBԣ5k,X@B1c͛7lr)':wm濺m;vС/"99Y.s89s樼Ja'] +W̟??>>5˗/ϧ83^n;vlFFF]]kL/_\zjm\XXι`ȼgώ5 !dooOP(ܼys]]̙rB\.722R.cV\vM__A TkpРANNNkNT*߿?B/99YPD"ݻ⊊ BnCCuׯ===[MxoCn nfaaH$222211D!___D`s\ru\V@Ǵ6t$Ill@ "44gbAfffٌ >vZP\GEEQ@0tb Nj}v'_X]]b KKK>Ckt??? Z_aYm_S\t5*t***bq D"ѣGThױ'888++:AkcǎWp87onp5NiiH$211122Dj6NDppK(tqqqAx<q##bkͧSTToaa!={Fa㍍B( 11Arss>}WX>εй~DDϷ}MdlODä{-Y\ѱGp5FNVVVpp0qpp}53MKK{BJW5?}k-as%rH{||<{iiiBFkpƄNbbb@@Bw9xL&[ύ7"""8@ s:r>>>'&&b6w툈gcc#pW\9_~#G<="EGGԞsS:... 6{IttrjOii)4kĮ!'8;;s܈7nந˞?"E}}=NYl /_bkkkr͝;wBAAAHHۺu:?dCCCwwsfffv ҫWbccmmmɩ=W6G 84&Ċh333rMAA <ֶ)66H$gΜ!_˺;wp8]zHGGGrjիWUn/^ %k\ӧB%%%I4O},,,._LGiii#GDDa&Mj~㣏>bx"h= Ça:IOO'=<<D_®~Q+wޥH9 X*dEEE۷o'ׅ@mܸ;mh: "44t޽zpD{g&u֭ 333SByjjjrrr֯_okkkaaNCoHKK;v,yC–'Nzw(lm\ws}U')Cf{ B.zW\INTH$:tPUUH$IR [=B(??f纫(9+WoZv [^^^TTdz􍎍0arŋm?ZU9fС4k@ 6n}k1W\AAH$244455DԶuVwwwrL&ۺuw_T#z.L.tO8JNNFZCZs!1]ӧObH$Fzz^kΝ;G@*>}>J理Bbcc{IoygXXXAAjkk8P\3pi9S[nzzzo-#8NO_PPPm5SL9)уxMZnmʕzzzz/n sNjjjbcc8Nhh(,qVVV|>?***//wEJs>..ɉ)d_*//D"Us l됧'B( %%wEj)..Dbӧ+b8:-C" 8w:r~X,ң\Zg+tHr<11!)ݽ{744HAl %C}cU233i5NNNqqq+oee%++++DN!kOMs[aC ȩ=eee | -B06T<~4.ϵƥ)4,td2ٚ5k\nhhh^^X,677'TCP($"44r|̘1\.Rƅ\t ]ISRR2|p##xcbb,--ɩ=ž<׀*4GGG@¿cԞANLQNݻ:q8ղ ;׀ _~?BBo=ڵkM*Oټys;|>ۻTAW1pX: B"̘1P5K95..{777wh &#055򲳳!k\? @n\} 2___ 'NPٳgɭlll >7odϭ#wSSSrb1 g\ۓ䧟~]`Ydgg BWW۷ow==QFڵA4IIIApܐ􂃃 Eff%Ks=t˗)tN8ajj:rH5o⴯ !t!:_jՐ!C?YYY={tssx͚5kĉ4yk֬?~9sOKKK$HBt47dffZYY5322 q\nnnyyyHҨ/~ڸqM122(-ڦ,X 44R;ѣGL} Ѵ̨3gNbbݻg͚ di鴃C {nח9::EzjرɧOf&q!M>̙3/^/**RrssCvBѣG.] dX.p8~~~W^U155]:Çd/^$'0oOx…ݻc%ڭ:a۷o>G  211?"###""6oތ؀w=z۱c,,,>:BH"p\Ϗ[xqEE"ziU:FC#Gӧϱcp5jkk Mk֬qqq?~~~mY.؀+W>rGlqIO~mBddyxxxUU \-Nzo ۫Wȉr=+WÇg,qPJ$BhҤI'O<{qjjjpZߺ"xj=nܸ߿yZv{wSSSܹ{=w9=trrrF흘Ȇ,R8p`JJJiiiHHׯq8NϞ=#G;))%oyyԿ3g?|=h O=֖=X|y;拉=﨣͉ ;B&88:ǔ͗WJgϞ}رc:Zpy-^\\Ķg,RHMMχܡϫqh ?0--ɓt_^)?ətݻw:tLJէWJ?vؕ+WfϞ OQB(x<(?OmTH$! :رc'NOqע |3iW\7oއ~((lZ! >;v̚5k<#{:/^ܰaƍY8mJiƌs΍zZ4l SSS1eʔHj v\^)ϮMMMk00#C>H$ Mk.HѸk0X:g\\ƍY>*ZlzEGG-[;v w-M*vXt9tϟ?m4xFނD"aT:uY.\˹wl QCocЉW矹\.ٲUXc?ӆ lmmi*Z bŊ]ׯ_ojj_9Nn|IZlϦv5jԨSN6 w9TTTobbsNrhУXExۼϞ=v˥& ZXXr \P(R)B(11q„ Xk󓒒޽˶%bYq999Hnp5_Sօ˫ǏlڴIS!dllCUhhرc,X@v@ |=S#H>ɉ(ЧO?7nmyyy7n+Vh\ccA::D"Yr%dԩzzz,XA7:mҥk֬] -_w:8t tޝ0q?dqCիW#bbbpF+Wl `w%mllo׺uqF_T~8NHHtH=Tw͙3G& K*j-/^_.);;pig޽{y<ޣG@8qB!am˖-qPWWףGxSNHtYnԩS{Ic1#z-XPb޼y={;;m200ЁȌj'222BE &L@Akaȯ_ZZ6'oE_|||?M2EP{**sε]7!̴QMMц hͼ^z^VVt¢w!׿L?[om>|\?˗3OM]]3x8coҥ}opBܵtك|}}.b֭]6o {͇3744, 3fl޼YC!}%=/^3\ ŋoݺz[$%%qܐt)%:#FuӢE>} 3_ -,,v؁ ̚\kFgϝ;_ms=3F;wY >.\XRR|X:.\иA\\\ƌv-CG.gff>K5V-:uTnn.BNk:>|,/Ǝk.܅2t_ׯ_?,Zqܹsڵ n'Zݻw=<\SSZNAA R3e2١Cpt#HpUDh"kkkKKŋ744t999~5W( &M 9~t-88Xwh#Gu}̙%%%+<{ !|( HMM%bȑ/_ܻwo'_)pe˖6wIɓ'¸su>!aÆfgg.x!dmm.pBRRҒ%K߯_K۷ڵk|y}}=Q8 秦8qYYYi߽Q~bo?YPPn:uyBS1]FޘxoGڿ?ΚP(Mի{S&W(4ZZ !G?(8=:Ul?!J~K~|J@@@gt$''ԔUwʕe˖9::R3rssoݺEa,'$###$$VOO{l[o.B!:Nyy9B[nd픔dddxyy}7l{C^ۛv}}}>~Sl'D$]p!33իW۶m;p@TTMOoNSSBc*^|200 %㲲R iiiiii|rЦMhUU Dr…ׯ744޽[f 4iSUYY) &M:wwUg}×/_O!j;Ŕ`[a#?LRV" Iq\/B޽{T6ʕ+-,,z"~[4iҭ[=z~SE'jӦMB}O={_QQ1`3grP`` ڣ١RB Z# SE QΆ#?O>T堠 KKK J~CzzΝ;i*RM~iiiׯO?~x5?!VZv}y{{T$Uۗ2z蠠 ܵGC'""!J~={j]z!4}tBǎ#>Bh̘14>iҤ'OP ٶmB?D566R"EN<9o w}ɓ'4K+ ~SL<7Ay :tڴi}{l=pW H{:Ak˖-FFF(GaU}ut&LPWWיLPBG0hĈlh @#Fq9pAP(`@+,  !4bĈlr!hBhذa/.h?Bݺultq* ~?>uԼyvE"B\/;;w!B"ܹ׭[wersbmm CAS]]}ĉUV-\pEEE+oo7oB'888,]\D.*w9w\P}!tx{{CO1k׮ms&rti̡O.eB&&&xlUп\@dR/!!ؘ'&&у|3ɵI1+,,l~~~ X?+nnn2X7^_ĉ97&+FLJJd /abbafagpLQ$tɒ@{۶mV9-|VVV X[ٳ?#|7|?;kggBUX___ 7l_-Z: By|>fff^=**ի ܲe ) WX8::>| +W?ݻ˗?EM2ŋxxt0 { ?׏9|pZZڀ` xwqM]Ož*ą nQjZV՟uઢb*ֽ D@PCe>O BHn%7~3p9۷dW :.zѐ!C<<<|pSN]N7 t? "['&BHKK'AHOH!Xv@>>wss=rH aڵׯ_"CSlmmLgqQ\pB ,,,%%@ tWQQ葩SZ[[Bb#QrJt ߄SԄ֕ëg"Ə8n8P\\ bs!p3k֬KSSSM&fIII}!oW_}%Zs,ͱ0f777,++CIT|m;FݸqIGGGfǏ/m#HAu&cٲe?2:!===GfeݺuFFFx "!ϟ5k0L1qD\JNgʔ)Ǐ2:>}Bb?bKTWW󞐑`0mBXTT$G,^^^b4i$\N 7A e111="&á, /{X!˥hIMM4h$''[ZZJKPGGx ]Y`A]]ŋ{ NB>m۷8ڵk{űBܝ?~̙ⷓ$VH!&t`ԩ! 6˗/>}3fMihh?~BөD\ŋ?SUUCEzt 7+ .LNN.--~ Э[(D_ߟdU$rssutt,--l'--B}?OEzt 7SӧO/bbbzNۛvd@.ݷoϟpMMM\.~YfyF䪸ȳvڟ~Iv.\,~;&:z~s`cccRRRhnwo.֬Ycjjf|lNCC7|ӷo˗׷}ã-OMMݺ"rU\ɄUnnoӦMC19{ؙ&ࢨB$'' [md.tԾ'O .D(.@:{]...s:@7oիم|…Za XǏ| .dd2ҦLBv!@7ܹs<BGܹsdN:B={͛7kjj}&ILS{ IDATL166& f͚f\3!t͛7 HH>}Ǝ+(++{1ٳg_~kX:"11QUUU{?͞=b]vM tEbbمBp8III'O& f͚u zA(NI򪯯hdddkkKv!@ΙXZZ BG!ܼysr<'NLNNW[[ V&Lw!t_jj*Ñ0aB(55'@ȿ7o9wd#ցБpl$t*%%HBIIIqqޡŋ#G]^x ,&Lm۶W^v|бBHKKΎ*Bիd" P _`` %HjzzzC9>>Ϗ8m׮]6mz6ٵ(..B/B(>>B䄫Ç;>tBh,K~3+**222ğ=z46VG:!Իwooo?Bpvee対BqppxQCCCLJ t+444???//BtI&ijj]P8l6;??C:>dȐ( MmmmJJ [RXXX=|C:ZdӧG%&&Xӧ]PPvvv=B_rم̙3d]AAA:՝3gNdNyy /^Lv!@q 2oi'44K}2ɓdmmmmyy9rv\\\ &맓\cTUUɮ(. C[xq\\ܧO.DtϞ=[d مf``QRR·B߼yTLN1bСC.(4 2p@uuugϞ]`م PZZʷBd"Gl dqYYBN=zĈx:e݋/իٵ !t `pi_YYwߑ]!ddd;: 鱱d\.t$g``P__v!N455Ν{ak֬!KOO!TSSv!N-[VTTt ֮]GEv!N~ɍ7VZEv! BBCCϞ=[UUEv!۰aȑ#a UB|@ﯦ&.\a PSSSۅ:9rDO'oٲӓBhGYY!v!N7BCC矴4 Rnnŋ7nHv!hT*Bn :YO'o޼|҉NCXhh{ ă\~z s,F]=___MM͘ իlZfcgvx t6o޼(Cv-;w.55u߾} Zv`E.ҥK_xqm Wss?8w\GGGksu+͘1ct+**~7 K!mm !tz…CۓǏ7o 366&u:C@GWWWJN'o޼YUU.Z)##G~:ׯ: Ё+хz*992.]joo|rr[:h{:wΜ9sRiWVVfhhwKYȨРo>}СC/_L&ԬZjɒ%0R׭[Phh(m455IO.-gggUUU;;ϟ?ST˦&b&_lmؖ{فCv…Ç'@yi.PX,VBBرc̚>QnF}m߾wiĈ `٭@իW&&&| !t뛑rY,ߣY|aN͛7} N "S\\laaBG(ÇWRR7Iy޽X8@Q00E?}dnnηB9tдi:KJJ6lO?YYYItCƆo!B2d5)%ɓ鈈J 6ܑ]dڵk%5|%vSh4Zpp0Yȓϟ+++9ѩ]vظcH4tbbbܹpf.ad#Omll:@@>}455ێFR%:>|Xf͊+ &M(8ѣGΔQTGG[|(((:th:=cnn~M:λɒFI.t.\e BOB^ :.1xTr{:QQQ׮];y򤺺$?|𡬬ֶC:#}}l6=={8qHڜ9st:N={6ٵȉѣGw]\x1"czzz&M¥ALAAA5|p92#f[dooob6rӧ-q{O>Ji;Kw||-&5JB.ۣe޼ys]9|}}.g؋'Iy#ĉmfdd0n.8::u55)TjTTANNN~~~kk+I|R 77[!DFF}!dllZlB())H%Ν;Ӛ:=vر۷oR(-xDX<<>BHjjqRSS6C4pNйyҤI&R+0._u tl}||F{㰧wB =@;o߾W^mcc#!t\R__?""BB_/^oܸ!Dz€=~~~SLV t^SSsNn!;wX=*--o-Z-mAlvPP޽{ ^mۖ%VB=Zvv͛7n8bb*//'l:(iӦ;wNI3-pNիwjii]O:u9+++7 W(ׯ^:""b֬YoB`0fϞ|r# Bk.j@QN6166J%wB3f+..NYYJ򯦦fʔ)YYYzzzĉkkk322$=l0 tgXԤ]B:ȱZOO߾}[JdUuu)SJKKoݺ5h r!//A o=z_]?JffСCH:)Dž Lzybrb׮]gϞ1cƹs.KpԴ`ݻw\r˗/9B7Jnni j̙>LHH `*AEѪ\n6449lȞ?>k֬ʛ7o]PPP&&&cƌt*ڿ+W=ZYY9''GVAE$CҀb\rƌYYY2qO{:4mΜ9#ooCEFFFEE]Q@ť7ydv!F|TVVv) EGt:?dWlC\]])q!??V???kAEEEnnn+W OOO "AƎ?vXhiiYvy dWOAECh4󟖖R5jԁ<9x`R P\L&sK,qqqqqqYdL&ae455mڴՕNgff88m9so rÇڪaaa/_Ė|2,,LUUU[[;<<Ǐի{immP,o߾ TWWpuuuMMͰoJS԰0Mz@E eee==*ϯSVV z9^0p:>jԨ\:@=}4((NFFF nmmmdd!N z\zuڑ r<BȳӧSTcczک466RӧOm, !+*:@>eddL8!4hРflnn8qbff+//_ͥKƌ1bĥKl6x>1c\tIoޫW/CCØ܋E:@N옘aÆ!/]p$9s%GGGаa6pbbbLLLo.25&&!4}tA vgkkNMMuppPRR 22dFFFQ(ӧ߹sJ )#B0a;}t\m Wcc;V^˗/crHzʪ'\*ھxӧOJJJ!!!dWį8$$DIII__?""ӧOdW$] t(// RSSkaJ:aݸԴɮHZ@͛0 J+VeeeDDq ՞={uիWDDćȮH|ݸ={FvEdRɓ'شX:yűc _O555KK dggPER}||Sލ/_Μ9SGGb BHlTDnޞ7k566`k}d~?۷/J믿D655EEEƕ#Nk=ջQUUe``6d###%W"eo++\itVbb"BhРA◄]S3fLrrm ڰa˱-,,$X@ t).X܌9Sx6^K.1Dk0_-ǏB+ndb'N>|3\OOO 3f[V)..F8d:Jrvƌ#F8qk?MF@rX'Nϟ? #++S:'ꮯOJJ;wmBxzzfee1 cc۟8q7ٱ5Fa-B(88XkWX)SSSTFF.Zm 4ɓ' idd$ķ}ƍMMM%'BD7==-:\.h޽$MKK۷/B(<<ߖڒ7 VTTF:tH+B3txܹ9r$~ud؞3|hjj5j֭[\'ܹs!S @IIIXXJ>}"""%-B!_iTWWGDDGEE%,,D[ .q8nׯ_GHhc)--m+L[+t222B666_eeeٸJKKqOѣG---?rlѣG &`߿UQQ y5^-766&%%ukZL&355[˗,2>>~ %..\ׯCBBTTTtuu#""޿c|z7222Κ*ݶsssB/^YTT$~.:;;uJAIDAT{xxN722NKK*LQQ6W޽oNFW_J\vPAA6@^ú&ݻww=sY~D*څϟBׯ_'0 SؽQ2dF 8'_7. |yPP1O`B֭[NNN!Ǐ X622NURaa!a 22G'{ ݂x]r7n\VV׷ƕ'N1X)ccH)::`kk?\ |BXg#G&%%֍!4qD3'33}a``%1a]LL –!&L`0$T"UV }777nPb2tnn iMMM۷on#O:pԩƥ(ܮ0aĺ.[VTTZjd;d PX`ɓ' (.0te˖M2ٳg% 2݄Nccٳg ('''??!C|JvQLݏ_xj<)++ q8u-[TUU\~ӧE%ll;;aÆ:uJ5YrϞ=q '( =GѶlLBBvc1${:iӦh4\ZZ333}||6l؀ zvsO<9zR&M;v,NȈ=ճб^tMjjj$TNϟ?5jTuuuRRRjj E"""8κu$Q B^ 2dH~~3gx N޽|...f!. GD]yϞ=JJJwf Z[[?|@vE@>xxӧO󵴴B@$lm۶-]t͚5d P(Ǐ7668Xlٲɓ'?{%'}ݻwѣG]WA0ovvv/^Ɂ)v߾}{BB. UTTܻw/..pc1 ^ -Zɓ'&&&x5 ۷8p@[[{pc1ߧͅˮ䪫۵k9ڵkWXAvQ o \\\ L@]v555}aaaz"(s ^|8v3g"a7_eeUV^OvQ333s]xqǎ7:r-[6ugϞm߾H'Loׯ_Dd'''???[[[ltKuʕ_9s222$ `0\]]'M}x H? N/}᯾/˓VÇ'MNR FRRѣ. H0th4ɓ']\\BG$i9V\\;r>$%%]= A)++߃ >> i*B֭Qmɟ>}MC9sFszc͛6m搨EE$DztDMa|رfZr]=%iW>aaa؁^uuʁȮU<|L0̙3dW$Azzz!~Ǐ]BЉ FX!O:,`xl0l3g͛0`@nnnNN-33֭[FFF?=Q>'))iFFF!*l2;;***ƍ۽{7Bĉd@gؤ$]vU1&O.c dcO[IIIuuumw#G]tА!C.I8qbڴimblv-XNRIݻwB| م= &`00LPSSSfffۅ=ںuߍ9o޼YlYUUB1%%{=f9''gΜ9CmzKKKVVT1-,,fϞիW,\1nCɝqcW/ϟ?>566v[0w$wUƷ~>rlDIdй#| bNطo߾}.I@.A P:BA P:BA P:BA P:B9r/a@[EBBBhh(YHU (R20@A9 t B@>82̟IENDB`tins-1.1.0/examples/ones_difference-mtm.png0000644000004100000410000011167412321542746020773 0ustar www-datawww-dataPNG  IHDR|4*bKGD IDATxw\3[MJ56JQQ * +ƨk&A7YM#1Xbcl[ (D myܽHٝ3|{YgyfBP ` w`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA .\x5U< t[l]B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B(B.]k.)))ѣm~,Y28UVK&9::2_.Mjj ˝5ksRPPuV~=H8:B0dRy<ޜ9sp+//۷o7₱*0DFFr\A 0G@̘1C.+p8X`322p8666`TDD A:Q!P(t `TnFI ]B0mΜ9 bݺu] @7} H&<~x `۶m;xzBB(p0܅@O˵/'AKo{:FA`Q:FA`Q:FA`Q:FA(SPP}3guUěCBBN>M_Pm%@ɓ'{I_U[[̗}=x>ضm=E `@ (Ya\4rСC{#c@&@zB t/++C 06:uWZeooqFܵA&uk,}}CY@@Q(K,A.BKLLˉ'֯_@ .;v "::֭[ԃxↆ3f.P BP.%%jhhx"3g/ݻ7k֬ VM;otl+ (cddݷmk``zԨQ&M:z(y5bĈ#G9rUC:2ꫂr9eQ "FMpy`Q:FA`Q:FA`Q:FA`Q:FA`端ںuk_P455|jsss_4k/ʕ+=zԥܽ{cƌr*̙3*׭[׭[7B(!!a{9sj-[nŊpJ_W{y.]r 233 xc( t@UWW2.%%Sݓ'O\;w޶G 2]##""$ɁI'O d2蚯Ӈѣ:V?N]p5klذaСj6ɯe2۷?v@=YyyyC 6mږ-[o- \.o߾7n܀;;ZBtJmm lM*444'Ǝf t/^=zTAݹsux/BA耎[ vvv4xORiVVVrr2%:p>,&&& 6/_y<ի: `'SPP0x]vQج[~~oVV)<`VuuuA\xАfuP(|>AMMM䇐yxx$%%Qx86x geeQzzz...'Oζiz:m%KN<9zhZt)SH$ZXamHKKDN@ P(th,,,lҤI?8P(D2p,: ӦMܹs'33ufnncn$7|'411a:vܹiӦ#Gxzz2y\@; %++룏>ZjդI>P(+BŋSN1bė_~ѡS td|>2ccc# ttWUUɓ vZܵ '''%###ܾ*Bz:: `An_uyܵ @ ]`tt}ƍ߾*0TGw@蜼ٳgϟ?kPX\\,qh[jkkLҧOw-oeee ! "22ŋ -}YWXBG[رcj* Cxz+N>vZܵP=-$J}~A~AA̙3#"">c`hϧ]|ygʔ)Bp͸Kk:Z~xR4))O>/))|* /BGH$#GHRPSSSIIIII'|B>b3@PTTP(Ytd2LwEGGd2uH ={ w!^:fmvWWW3_R'X:BG;v\.?+$O͵V?nN Yf}gY<z:Zn$kݻw r{}aÆa`.xYjjjk+>;w?ql=Am6wwwUu@ ~:*=C{x;w}ւUl̬[np[Gk)@' 8k?nkk<66UKEEEmmszںuj4jAٚU() thaCCׯ5 !iӦNhזFFFAAAoUl 6b:;r}||lmmcccB4z5Qڷ O͵v9n8k777B F t6BGAnРA\.!rkV߸q#5Qڷ) ) v- .\iii|?tМ"|]"r9 J:Ϗݳg /W(K,AR]e|$r| \ai%444\2 @Fbbb\\\N8~z k%o!diiijj CD"ʕ+B BFwADtt[MKV:Lضmٳg7 rɑ,* ZxqCCÌ3ꨭSMM thx\ \ f͚6_pE3g466^dݻwo֬Ys"6mv,奭 th7uT2,8Ό3 6_k``3jԨ0"ȑ#NNNTey]Kyi+˜vxRedPP\.W,9̺5@PZZ*Jyyw!J:`,^OOnh^z:ZB >:੹} tWo[Wh"j@"<w!2:?}tB LLLpV>dҽ/RYYzjZ҂rrvrppr?@TZZ: >Ro,a9\.KIGKA0- e2X,Rf!h:y{{7 ~qY`a8p`@7K`)/MᆱG~p<=='M$ 5Ea Nޒ4@ (** *ߟLhxx84P(lhhx)B t0puuEzj\%aZvvvvvvPPB2""wEޞýdÜc\r!m``. r!t4N:XVVo߾}IRБ#GOixj th$Jwݷo߱cǚݼy3<<<<<޽{iiicƌ۷ݻO5-ׯ_>wܞ={'%%X+gذaIII/^ٳܹsׯ____f 5P6&&G\.7""͛y͛7#""\n=bbbjkkSرw@E:VVV|>?***??-EEE|+++X\YYIGZ 55!s܅U@PL$DǏǏE"H$*//Nz*B* tR\\,bӧOjӧbX$Sղhllr]P>>wdKc@ ]2VbTeOO9s8;;edd5 w]m5jԥKҜ̙e]`i0wYD" B BCC_~zhh(AB066V"ஈFuuuA=zw! t Z,x[nuGm۶mƌU i]t-rX,iQ;ҼܹC߁lmmׯ_O_&: S"H S$//Юv%ə3gW|hΝ666WB/ƕwUUUEGG#|||;СC>9aH$ߦjW_uiD"###rWYY vh͚5r\Pz !dmmM߱O>uT4)**׷Ϟ=eBԢgϞb rOQQ%ͶI٥z;g}6p@4ѭɉݻwcT?lذ.!jFUWWXZZ oi̙\v?leeE!t%t9}ӧO˔WHNrppp8׮] b䛊hhh W^>ΥK pwwB˫<<55!'P۸ҝ;wB> tə0aA={_>tjjjrrr֯_okkkaaNCSWWyfr\ĉ)_7c!jUA?~M9t>3CfHՍ/R~OmΟ?occJ6׽{͛7>6OoA``2+!t}P( $ jANӧ6`i"mrV+W¼4bVdvv6ݔ#w LKK# |.˗B-`,Ŝ4򎲋Kll,x$Irrr~~~mܹs RӧO<(ؿ?*XqZZ+ WW)S<|077XA,_חt(tH7n &9;;S8+4 |)SΟ?OIaXgggr7l onҥFFFܴiL&@.MvlsCsNDDdz/_]]^|)ɹZѣA.t@$EGGWTTஈJfff"wEԻqB6,::'ODGGDD95::ɓ'+˗/BO]<\,w֍a*77wE%w֭X,օwͷlق :oxyoy}uֽ{ȹvvv3#W]mSSe˖gϞӧτ pr}={~]l)BhfPK IDAT6/[,??Ν>D(Yݵ֬Y# k%$$丸 2d˖-B8;;COG(%i\S媵S^^.LMM [OJbDDDh]2vعst>}*̌:X$O7-,,|||=zDE?1b*@gAPehhHΥxa^x!>|د_ݻ:u5ط~₻ Y:8qA+W#Gܻwݽ{744WMM {,۷oϗJ CcǾ{ >..ɉʕ+/dff999ũvj\\u:ud@!ݿ G*"H6l@Fϔ)SLp7lؠഴ4;;;77[nٔ*--Eѱ3,Ya{ݻ)kӧ#F044ܹs'Umj\n``g܅NQ]LLL֮]p1MMM(ZNf'ww wS`p v܉?>x111{GY^^px\s C%\iӦH ,̘1#+++55K X@h*?~ѣG˖-(ěZ^zeff~}lA tnܸq /&$$|WW9sfmm-P($.t BkZmo۷E"B4:hР㮈^ӧ С͛===Ǎyw}}}> B:Ԩܽ{EضçMrJL"Z888| tc7o<܅A__?..n׮]6l=zgpWD=.=:mKLiӦ9syYǏ4ʕ+ˡ<5:HJJ*..^t)B:s޽{nݺw9 46l0fwww܅t{'OFFFᮈ2:uٳgQ"'&&;vlذaZ;:ڴiS^>܅t\"J tiP@(~w!:jسgϒ%K3233'N8nܸ5kr6:jٶmޜ9sp";vl޼o d\5 tT'J7op&.?=͛7oԨQ ^HHHfffEEŠA]4, tTӽ{~G ˗4hA@PUUU]]Ul۶$22w!4255=xڵk͚5K#$AtYSSw-"bٲe)))gΜ]QA:,eӧOIygeee 0ȑ#i a9.۸qĉɞptt %NlܸqРAÇ]{EEE߼yԜ t:VZZ;T6hР,r*z:,ӱ8KK3f.DXYYZ~B t:P__믿.X@__w-=zFz z : BZhB4ĉ\B.?x%&- Eqq1Bxeiiу޷o9vSN]  drKy)X = &333AGedd.JX>O.?A̶ṉ@WAO r!P(*++wMW_}'UeAf:on.MMM ӣG4hPbb"4Z``rG}86yCeeeJRЍ72 .,Zhʔ)t/?` AIIIDf~ƍ'LK`:\.f4k֬ Z3.yCee%τ$$$t~wUUU 0`…/d2YiizeZ@輡kX͛CBBԣ5k,X@B1c͛7lr)':wm濺m;vС/"99Y.s89s樼Ja'] +W̟??>>5˗/ϧ83^n;vlFFF]]kL/_\zjm\XXι`ȼgώ5 !dooOP(ܼys]]̙rB\.722R.cV\vM__A TkpРANNNkNT*߿?B/99YPD"ݻ⊊ BnCCuׯ===[MxoCn nfaaH$222211D!___D`s\ru\V@Ǵ6t$Ill@ "44gbAfffٌ >vZP\GEEQ@0tb Nj}v'_X]]b KKK>Ckt??? Z_aYm_S\t5*t***bq D"ѣGThױ'888++:AkcǎWp87onp5NiiH$211122Dj6NDppK(tqqqAx<q##bkͧSTToaa!={Fa㍍B( 11Arss>}WX>εй~DDϷ}MdlODä{-Y\ѱGp5FNVVVpp0qpp}53MKK{BJW5?}k-as%rH{||<{iiiBFkpƄNbbb@@Bw9xL&[ύ7"""8@ s:r>>>'&&b6w툈gcc#pW\9_~#G<="EGGԞsS:... 6{IttrjOii)4kĮ!'8;;s܈7nந˞?"E}}=NYl /_bkkkr͝;wBAAAHHۺu:?dCCCwwsfffv ҫWbccmmmɩ=W6G 84&Ċh333rMAA <ֶ)66H$gΜ!_˺;wp8]zHGGGrjիWUn/^ %k\ӧB%%%I4O},,,._LGiii#GDDa&Mj~㣏>bx"h= Ça:IOO'=<<D_®~Q+wޥH9 X*dEEE۷o'ׅ@mܸ;mh: "44t޽zpD{g&u֭ 333SByjjjrrr֯_okkkaaNCoHKK;v,yC–'Nzw(lm\ws}U')Cf{ B.zW\INTH$:tPUUH$IR [=B(??f纫(9+WoZv [^^^TTdz􍎍0arŋm?ZU9fС4k@ 6n}k1W\AAH$244455DԶuVwwwrL&ۺuw_T#z.L.tO8JNNFZCZs!1]ӧObH$Fzz^kΝ;G@*>}>J理Bbcc{IoygXXXAAjkk8P\3pi9S[nzzzo-#8NO_PPPm5SL9)уxMZnmʕzzzz/n sNjjjbcc8Nhh(,qVVV|>?***//wEJs>..ɉ)d_*//D"Us l됧'B( %%wEj)..Dbӧ+b8:-C" 8w:r~X,ң\Zg+tHr<11!)ݽ{744HAl %C}cU233i5NNNqqq+oee%++++DN!kOMs[aC ȩ=eee | -B06T<~4.ϵƥ)4,td2ٚ5k\nhhh^^X,677'TCP($"44r|̘1\.Rƅ\t ]ISRR2|p##xcbb,--ɩ=ž<׀*4GGG@¿cԞANLQNݻ:q8ղ ;׀ _~?BBo=ڵkM*Oټys;|>ۻTAW1pX: B"̘1P5K95..{777wh &#055򲳳!k\? @n\} 2___ 'NPٳgɭlll >7odϭ#wSSSrb1 g\ۓ䧟~]`Ydgg BWW۷ow==QFڵA4IIIApܐ􂃃 Eff%Ks=t˗)tN8ajj:rH5o⴯ !t!:_jՐ!C?YYY={tssx͚5kĉ4yk֬?~9sOKKK$HBt47dffZYY5322 q\nnnyyyHҨ/~ڸqM122(-ڦ,X 44R;ѣGL} Ѵ̨3gNbbݻg͚ di鴃C {nח9::EzjرɧOf&q!M>̙3/^/**RrssCvBѣG.] dX.p8~~~W^U155]:Çd/^$'0oOx…ݻc%ڭ:a۷o>G  211?"###""6oތ؀w=z۱c,,,>:BH"p\Ϗ[xqEE"ziU:FC#Gӧϱcp5jkk Mk֬qqq?~~~mY.؀+W>rGlqIO~mBddyxxxUU \-Nzo ۫Wȉr=+WÇg,qPJ$BhҤI'O<{qjjjpZߺ"xj=nܸ߿yZv{wSSSܹ{=w9=trrrF흘Ȇ,R8p`JJJiiiHHׯq8NϞ=#G;))%oyyԿ3g?|=h O=֖=X|y;拉=﨣͉ ;B&88:ǔ͗WJgϞ}رc:Zpy-^\\Ķg,RHMMχܡϫqh ?0--ɓt_^)?ətݻw:tLJէWJ?vؕ+WfϞ OQB(x<(?OmTH$! :رc'NOqע |3iW\7oއ~((lZ! >;v̚5k<#{:/^ܰaƍY8mJiƌs΍zZ4l SSS1eʔHj v\^)ϮMMMk00#C>H$ Mk.HѸk0X:g\\ƍY>*ZlzEGG-[;v w-M*vXt9tϟ?m4xFނD"aT:uY.\˹wl QCocЉW矹\.ٲUXc?ӆ lmmi*Z bŊ]ׯ_ojj_9Nn|IZlϦv5jԨSN6 w9TTTobbsNrhУXExۼϞ=v˥& ZXXr \P(R)B(11q„ Xk󓒒޽˶%bYq999Hnp5_Sօ˫ǏlڴIS!dllCUhhرc,X@v@ |=S#H>ɉ(ЧO?7nmyyy7n+Vh\ccA::D"Yr%dԩzzz,XA7:mҥk֬] -_w:8t tޝ0q?dqCիW#bbbpF+Wl `w%mllo׺uqF_T~8NHHtH=Tw͙3G& K*j-/^_.);;pig޽{y<ޣG@8qB!am˖-qPWWףGxSNHtYnԩS{Ic1#z-XPb޼y={;;m200ЁȌj'222BE &L@Akaȯ_ZZ6'oE_|||?M2EP{**sε]7!̴QMMц hͼ^z^VVt¢w!׿L?[om>|\?˗3OM]]3x8coҥ}opBܵtك|}}.b֭]6o {͇3744, 3fl޼YC!}%=/^3\ ŋoݺz[$%%qܐt)%:#FuӢE>} 3_ -,,v؁ ̚\kFgϝ;_ms=3F;wY >.\XRR|X:.\иA\\\ƌv-CG.gff>K5V-:uTnn.BNk:>|,/Ǝk.܅2t_ׯ_?,Zqܹsڵ n'Zݻw=<\SSZNAA R3e2١Cpt#HpUDh"kkkKKŋ744t999~5W( &M 9~t-88Xwh#Gu}̙%%%+<{ !|( HMM%bȑ/_ܻwo'_)pe˖6wIɓ'¸su>!aÆfgg.x!dmm.pBRRҒ%K߯_K۷ڵk|y}}=Q8 秦8qYYYi߽Q~bo?YPPn:uyBS1]FޘxoGڿ?ΚP(Mի{S&W(4ZZ !G?(8=:Ul?!J~K~|J@@@gt$''ԔUwʕe˖9::R3rssoݺEa,'$###$$VOO{l[o.B!:Nyy9B[nd픔dddxyy}7l{C^ۛv}}}>~Sl'D$]p!33իW۶m;p@TTMOoNSSBc*^|200 %㲲R iiiiii|rЦMhUU Dr…ׯ744޽[f 4iSUYY) &M:wwUg}×/_O!j;Ŕ`[a#?LRV" Iq\/B޽{T6ʕ+-,,z"~[4iҭ[=z~SE'jӦMB}O={_QQ1`3grP`` ڣ١RB Z# SE QΆ#?O>T堠 KKK J~CzzΝ;i*RM~iiiׯO?~x5?!VZv}y{{T$Uۗ2z蠠 ܵGC'""!J~={j]z!4}tBǎ#>Bh̘14>iҤ'OP ٶmB?D566R"EN<9o w}ɓ'4K+ ~SL<7Ay :tڴi}{l=pW H{:Ak˖-FFF(GaU}ut&LPWWיLPBG0hĈlh @#Fq9pAP(`@+,  !4bĈlr!hBhذa/.h?Bݺultq* ~?>uԼyvE"B\/;;w!B"ܹ׭[wersbmm CAS]]}ĉUV-\pEEE+oo7oB'888,]\D.*w9w\P}!tx{{CO1k׮ms&rti̡O.eB&&&xlUп\@dR/!!ؘ'&&у|3ɵI1+,,l~~~ X?+nnn2X7^_ĉ97&+FLJJd /abbafagpLQ$tɒ@{۶mV9-|VVV X[ٳ?#|7|?;kggBUX___ 7l_-Z: By|>fff^=**ի ܲe ) WX8::>| +W?ݻ˗?EM2ŋxxt0 { ?׏9|pZZڀ` xwqM]Ož*ą nQjZV՟uઢb*ֽ D@PCe>O BHn%7~3p9۷dW :.zѐ!C<<<|pSN]N7 t? "['&BHKK'AHOH!Xv@>>wss=rH aڵׯ_"CSlmmLgqQ\pB ,,,%%@ tWQQ葩SZ[[Bb#QrJt ߄SԄ֕ëg"Ə8n8P\\ bs!p3k֬KSSSM&fIII}!oW_}%Zs,ͱ0f777,++CIT|m;FݸqIGGGfǏ/m#HAu&cٲe?2:!===GfeݺuFFFx "!ϟ5k0L1qD\JNgʔ)Ǐ2:>}Bb?bKTWW󞐑`0mBXTT$G,^^^b4i$\N 7A e111="&á, /{X!˥hIMM4h$''[ZZJKPGGx ]Y`A]]ŋ{ NB>m۷8ڵk{űBܝ?~̙ⷓ$VH!&t`ԩ! 6˗/>}3fMihh?~BөD\ŋ?SUUCEzt 7+ .LNN.--~ Э[(D_ߟdU$rssutt,--l'--B}?OEzt 7SӧO/bbbzNۛvd@.ݷoϟpMMM\.~YfyF䪸ȳvڟ~Iv.\,~;&:z~s`cccRRRhnwo.֬Ycjjf|lNCC7|ӷo˗׷}ã-OMMݺ"rU\ɄUnnoӦMC19{ؙ&ࢨB$'' [md.tԾ'O .D(.@:{]...s:@7oիم|…Za XǏ| .dd2ҦLBv!@7ܹs<BGܹsdN:B={͛7kjj}&ILS{ IDATL166& f͚f\3!t͛7 HH>}Ǝ+(++{1ٳg_~kX:"11QUUU{?͞=b]vM tEbbمBp8III'O& f͚u zA(NI򪯯hdddkkKv!@ΙXZZ BG!ܼysr<'NLNNW[[ V&Lw!t_jj*Ñ0aB(55'@ȿ7o9wd#ցБpl$t*%%HBIIIqqޡŋ#G]^x ,&Lm۶W^v|бBHKKΎ*Bիd" P _`` %HjzzzC9>>Ϗ8m׮]6mz6ٵ(..B/B(>>B䄫Ç;>tBh,K~3+**222ğ=z46VG:!Իwooo?Bpvee対BqppxQCCCLJ t+444???//BtI&ijj]P8l6;??C:>dȐ( MmmmJJ [RXXX=|C:ZdӧG%&&Xӧ]PPvvv=B_rم̙3d]AAA:՝3gNdNyy /^Lv!@q 2oi'44K}2ɓdmmmmyy9rv\\\ &맓\cTUUɮ(. C[xq\\ܧO.DtϞ=[d مf``QRR·B߼yTLN1bСC.(4 2p@uuugϞ]`م PZZʷBd"Gl dqYYBN=zĈx:e݋/իٵ !t `pi_YYwߑ]!ddd;: 鱱d\.t$g``P__v!N455Ν{ak֬!KOO!TSSv!N-[VTTt ֮]GEv!N~ɍ7VZEv! BBCCϞ=[UUEv!۰aȑ#a UB|@ﯦ&.\a PSSSۅ:9rDO'oٲӓBhGYY!v!N7BCC矴4 Rnnŋ7nHv!hT*Bn :YO'o޼|҉NCXhh{ ă\~z s,F]=___MM͘ իlZfcgvx t6o޼(Cv-;w.55u߾} Zv`E.ҥK_xqm Wss?8w\GGGksu+͘1ct+**~7 K!mm !tz…CۓǏ7o 366&u:C@GWWWJN'o޼YUU.Z)##G~:ׯ: Ё+хz*992.]joo|rr[:h{:wΜ9sRiWVVfhhwKYȨРo>}СC/_L&ԬZjɒ%0R׭[Phh(m455IO.-gggUUU;;ϟ?ST˦&b&_lmؖ{فCv…Ç'@yi.PX,VBBرc̚>QnF}m߾wiĈ `٭@իW&&&| !t뛑rY,ߣY|aN͛7} N "S\\laaBG(ÇWRR7Iy޽X8@Q00E?}dnnηB9tдi:KJJ6lO?YYYItCƆo!B2d5)%ɓ鈈J 6ܑ]dڵk%5|%vSh4Zpp0Yȓϟ+++9ѩ]vظcH4tbbbܹpf.ad#Omll:@@>}455ێFR%:>|Xf͊+ &M(8ѣGΔQTGG[|(((:th:=cnn~M:λɒFI.t.\e BOB^ :.1xTr{:QQQ׮];y򤺺$?|𡬬ֶC:#}}l6=={8qHڜ9st:N={6ٵȉѣGw]\x1"czzz&M¥ALAAA5|p92#f[dooob6rӧ-q{O>Ji;Kw||-&5JB.ۣe޼ys]9|}}.g؋'Iy#ĉmfdd0n.8::u55)TjTTANNN~~~kk+I|R 77[!DFF}!dllZlB())H%Ν;Ӛ:=vر۷oR(-xDX<<>BHjjqRSS6C4pNйyҤI&R+0._u tl}||F{㰧wB =@;o߾W^mcc#!t\R__?""BB_/^oܸ!Dz€=~~~SLV t^SSsNn!;wX=*--o-Z-mAlvPP޽{ ^mۖ%VB=Zvv͛7n8bb*//'l:(iӦ;wNI3-pNիwjii]O:u9+++7 W(ׯ^:""b֬YoB`0fϞ|r# Bk.j@QN6166J%wB3f+..NYYJ򯦦fʔ)YYYzzzĉkkk322$=l0 tgXԤ]B:ȱZOO߾}[JdUuu)SJKKoݺ5h r!//A o=z_]?JffСCH:)Dž Lzybrb׮]gϞ1cƹs.KpԴ`ݻw\r˗/9B7Jnni j̙>LHH `*AEѪ\n6449lȞ?>k֬ʛ7o]PPP&&&cƌt*ڿ+W=ZYY9''GVAE$CҀb\rƌYYY2qO{:4mΜ9#ooCEFFFEE]Q@ť7ydv!F|TVVv) EGt:?dWlC\]])q!??V???kAEEEnnn+W OOO "AƎ?vXhiiYvy dWOAECh4󟖖R5jԁ<9x`R P\L&sK,qqqqqqYdL&ae455mڴՕNgff88m9so rÇڪaaa/_Ė|2,,LUUU[[;<<Ǐի{immP,o߾ TWWpuuuMMͰoJS԰0Mz@E eee==*ϯSVV z9^0p:>jԨ\:@=}4((NFFF nmmmdd!N z\zuڑ r<BȳӧSTcczک466RӧOm, !+*:@>eddL8!4hРflnn8qbff+//_ͥKƌ1bĥKl6x>1c\tIoޫW/CCØ܋E:@N옘aÆ!/]p$9s%GGGаa6pbbbLLLo.25&&!4}tA vgkkNMMuppPRR 22dFFFQ(ӧ߹sJ )#B0a;}t\m Wcc;V^˗/crHzʪ'\*ھxӧOJJJ!!!dWį8$$DIII__?""ӧOdW$] t(// RSSkaJ:aݸԴɮHZ@͛0 J+VeeeDDq ՞={uիWDDćȮH|ݸ={FvEdRɓ'شX:yűc _O555KK dggPER}||Sލ/_Μ9SGGb BHlTDnޞ7k566`k}d~?۷/J믿D655EEEƕ#Nk=ջQUUe``6d###%W"eo++\itVbb"BhРA◄]S3fLrrm ڰa˱-,,$X@ t).X܌9Sx6^K.1Dk0_-ǏB+ndb'N>|3\OOO 3f[V)..F8d:Jrvƌ#F8qk?MF@rX'Nϟ? #++S:'ꮯOJJ;wmBxzzfee1 cc۟8q7ٱ5Fa-B(88XkWX)SSSTFF.Zm 4ɓ' idd$ķ}ƍMMM%'BD7==-:\.h޽$MKK۷/B(<<ߖڒ7 VTTF:tH+B3txܹ9r$~ud؞3|hjj5j֭[\'ܹs!S @IIIXXJ>}"""%-B!_iTWWGDDGEE%,,D[ .q8nׯ_GHhc)--m+L[+t222B666_eeeٸJKKqOѣG---?rlѣG &`߿UQQ y5^-766&%%ukZL&355[˗,2>>~ %..\ׯCBBTTTtuu#""޿c|z7222Κ*ݶsssB/^YTT$~.:;;uJAIDAT{xxN722NKK*LQQ6W޽oNFW_J\vPAA6@^ú&ݻww=sY~D*څϟBׯ_'0 SؽQ2dF 8'_7. |yPP1O`B֭[NNN!Ǐ X622NURaa!a 22G'{ ݂x]r7n\VV׷ƕ'N1X)ccH)::`kk?\ |BXg#G&%%֍!4qD3'33}a``%1a]LL –!&L`0$T"UV }777nPb2tnn iMMM۷on#O:pԩƥ(ܮ0aĺ.[VTTZjd;d PX`ɓ' (.0te˖M2ٳg% 2݄Nccٳg ('''??!C|JvQLݏ_xj<)++ q8u-[TUU\~ӧE%ll;;aÆ:uJ5YrϞ=q '( =GѶlLBBvc1${:iӦh4\ZZ333}||6l؀ zvsO<9zR&M;v,NȈ=ճб^tMjjj$TNϟ?5jTuuuRRRjj E"""8κu$Q B^ 2dH~~3gx N޽|...f!. GD]yϞ=JJJwf Z[[?|@vE@>xxӧO󵴴B@$lm۶-]t͚5d P(Ǐ7668Xlٲɓ'?{%'}ݻwѣG]WA0ovvv/^Ɂ)v߾}{BB. UTTܻw/..pc1 ^ -Zɓ'&&&x5 ۷8p@[[{pc1ߧͅˮ䪫۵k9ڵkWXAvQ o \\\ L@]v555}aaaz"(s ^|8v3g"a7_eeUV^OvQ333s]xqǎ7:r-[6ugϞm߾H'Loׯ_Dd'''???[[[ltKuʕ_9s222$ `0\]]'M}x H? N/}᯾/˓VÇ'MNR FRRѣ. H0th4ɓ']\\BG$i9V\\;r>$%%]= A)++߃ >> i*B֭Qmɟ>}MC9sFszc͛6m搨EE$DztDMa|رfZr]=%iW>aaa؁^uuʁȮU<|L0̙3dW$Azzz!~Ǐ]BЉ FX!O:,`xl0l3g͛0`@nnnNN-33֭[FFF?=Q>'))iFFF!*l2;;***ƍ۽{7Bĉd@gؤ$]vU1&O.c dcO[IIIuuumw#G]tА!C.I8qbڴimblv-XNRIݻwB| م= &`00LPSSSfffۅ=ںuߍ9o޼YlYUUB1%%{=f9''gΜ9CmzKKKVVT1-,,fϞիW,\1nCɝqcW/ϟ?>566v[0w$wUƷ~>rlDIdй#| bNطo߾}.I@.A P:BA P:BA P:BA P:B9r/a@[EBBBhh(YHU (R20@A9 t B@>82̟IENDB`tins-1.1.0/examples/prefix-equals-suffix-reversed-with-infix.stm0000644000004100000410000000250512321542746025061 0ustar www-datawww-data# vim: ts=2 sw=2 et ft=ruby # Call with a binary number on the tape: # $ turing.rb prefix-equals-suffix-reversed-with-infix.stm 100101001 0. right :goto => 1 1. cond :if => '0', :then => 2, :else => 13 2. write :symbol => 'O', :goto => 3 3. right :goto => 4 4. cond :if => 'B', :then => 21, :else => 5 5. right :goto => 6 6. cond :if => 'B', :then => 7, :else => 5 7. left :goto => 8 8. cond :if => '0', :then => 9, :else => 21 9. write :symbol => 'B', :goto => 10 10. left :goto => 11 11. cond :if => '0', :then => 10, :else => 12 12. cond :if => '1', :then => 10, :else => 0 13. cond :if => '1', :then => 14, :else => 31 14. write :symbol => 'I', :goto => 15 15. right :goto => 16 16. cond :if => 'B', :then => 21, :else => 17 17. right :goto => 18 18. cond :if => 'B', :then => 19, :else => 17 19. left :goto => 20 20. cond :if => '1', :then => 9, :else => 21 21. write :symbol => 'B', :goto => 22 22. left :goto => 23 23. cond :if => '0', :then => 21, :else => 24 24. cond :if => '1', :then => 21, :else => 25 25. write :symbol => 'B', :goto => 26 26. left :goto => 27 27. cond :if => 'O', :then => 29, :else => 28 28. cond :if => 'I', :then => 30, :else => 32 29. write :symbol => '0', :goto => 26 30. write :symbol => '1', :goto => 26 31. halt 32. right :goto => 33 33. cond :if => 'B', :then => 31, :else => 32 tins-1.1.0/examples/let.rb0000755000004100000410000000246412321542746015464 0ustar www-datawww-data#!/usr/bin/env ruby require 'tins' LetScope = Tins::BlankSlate.with :instance_eval, :to_s, :inspect, :extend class LetScope include Tins::MethodMissingDelegator::DelegatorModule include Tins::BlockSelf def initialize(my_self, bindings = {}, outer_scope = nil) super(my_self) @outer_scope = outer_scope @bindings = bindings extend Tins::Eigenclass eigenclass_eval { extend Tins::Constant } each_binding do |name, value| eigenclass_eval { constant name, value } end end def each_binding(&block) if @outer_scope @outer_scope.each_binding(&block) end @bindings.each(&block) end def let(bindings = {}, &block) ls = LetScope.new(block_self(&block), bindings, self) ls.instance_eval(&block) end # Including this module into your current namespace defines the let method. module Include include Tins::BlockSelf def let(bindings = {}, &block) ls = LetScope.new(block_self(&block), bindings) ls.instance_eval(&block) end end end if $0 == __FILE__ class Foo include LetScope::Include def twice(x) 2 * x end def test let :x => 1, :y => twice(1) do let :z => twice(x) do puts "#{x} * #{y} == #{z} # => #{x * y == twice(x)}" end end end end Foo.new.test end tins-1.1.0/examples/ones_difference_19.stm0000644000004100000410000000121712321542746020517 0ustar www-datawww-data# vim: ts=2 sw=2 et ft=ruby # Call with two strings of ones on the tape: # $ turing.rb ones_difference.stm 1111 11 1. right goto: 2 2. cond if: '1', then: 1, else: 3 3. right goto: 4 4. cond if: '1', then: 5, else: 17 5. right goto: 6 6. cond if: '1', then: 5, else: 7 7. left goto: 8 8. write symbol: 'B', goto: 9 9. left goto: 10 10. cond if: '1', then: 9, else: 11 11. left goto: 12 12. cond if: '1', then: 11, else: 13 13. right goto: 14 14. cond if: '1', then: 15, else: 16 15. write symbol: 'B', goto: 1 16. write symbol: '1', goto: 18 17. left goto: 20 18. right goto: 19 19. cond if: '1', then: 18, else: 21 20. halt 21. halt tins-1.1.0/examples/length_difference_19.mtm0000644000004100000410000000100612321542746021022 0ustar www-datawww-data# vim: ts=2 sw=2 et ft=ruby # Call with two [ab]* strings on the tapes: # $ turing.rb prefix-equals-suffix-reversed-with-infix.stm ab ababab 1. right 1, goto: 2 2. right 2, goto: 3 3. cond 1, if: 'B', then: 5, else: 4 4. cond 2, if: 'B', then: 9, else: 1 5. cond 2, if: 'B', then: 13, else: 6 6. write 0, symbol: 'b', goto: 7 7. right 0, goto: 8 8. right 2, goto: 5 9. write 0, symbol: 'a', goto: 10 10. right 0, goto: 11 11. right 1, goto: 12 12. cond 1, if: 'B', then: 13, else: 9 13. halt tins-1.1.0/examples/recipe_common.rb0000644000004100000410000000274212321542746017513 0ustar www-datawww-dataclass Ingredient class << self def inherited(klass) ingredients << klass end attr_accessor :ingredients def ingredient(name, amount) name = name.to_s.gsub(/_/, '').capitalize if klass = ingredients.find { |n| n.to_s == name } klass.new(amount) else raise "unknown ingredient #{name}" end end end self.ingredients = [] def initialize(amount = 1) @amount = amount end def name self.class.name.downcase end attr_reader :amount def to_s "#@amount #{name}" end end class Unit class << self def inherited(klass) units << klass end attr_accessor :units def unit(name, amount) name = name.to_s.gsub(/s$/, '').capitalize if klass = units.find { |n| n.to_s == name } klass.new(amount) end end end self.units = [] def initialize(n = 1) @n = n end def name self.class.name.downcase end attr_reader :n def to_s "#@n #{name}#{@n > 1 ? 's' : ''}" end end class Unit class << self def inherited(klass) units << klass end attr_accessor :units def unit(name, amount) name = name.to_s.gsub(/s$/, '').capitalize if klass = units.find { |n| n.to_s == name } klass.new(amount) end end end self.units = [] def initialize(n = 1) @n = n end def name self.class.name.downcase end attr_reader :n def to_s "#@n #{name}#{@n > 1 ? 's' : ''}" end end tins-1.1.0/examples/add_one.stm0000644000004100000410000000060112321542746016455 0ustar www-datawww-data# vim: ts=2 sw=2 et ft=ruby # Call with a binary number on the tape: # $ turing.rb add_one.stm 1111010101 0. right :goto => 1 1. cond :if => 'B', :then => 2, :else => 0 2. left :goto => 3 3. cond :if => '1', :then => 4, :else => 5 4. write :symbol => '0', :goto => 2 5. write :symbol => '1', :goto => 6 6. right :goto => 7 7. cond :if => 'B', :then => 8, :else => 6 8. halt tins-1.1.0/examples/multiply.reg0000644000004100000410000000167612321542746016732 0ustar www-datawww-data# vim: set filetype=ruby: # Multiplication: C = A * B, A >= 0 and B >= 0 register.A = 3 register.B = 7 # Save A in T label(SaveA) { decrement A, MoveS1, IncT } label(IncT) { increment T, IncS1 } label(IncS1) { increment S, SaveA } label(MoveS1) { decrement S, SaveB, IncA1 } label(IncA1) { increment A, MoveS1 } # Save B in U label(SaveB) { decrement B, MoveS2, IncU } label(IncU) { increment U, IncS2 } label(IncS2) { increment S, SaveB } label(MoveS2) { decrement S, Mul, IncB1 } label(IncB1) { increment B, MoveS2 } # Multiply A * B label(Mul) { decrement A, MoveT, DecB } # Add B to C label(DecB) { decrement B, MoveU, IncC } label(IncC) { increment C, DecB } # Move U back to B label(MoveU) { decrement U, SaveB, IncB2 } label(IncB2) { increment B, MoveU } # Move T back to A label(MoveT) { decrement T, ClearU, IncA2 } label(IncA2) { increment A, MoveT } # Clear U label(ClearU) { decrement U, Stop, ClearU } # Stop label(Stop) { halt } tins-1.1.0/examples/turing-graph.rb0000755000004100000410000000057412321542746017307 0ustar www-datawww-data#!/usr/bin/env ruby load File.join(File.dirname(__FILE__), 'turing.rb') include Turing filename, *tapes = ARGV machine_type = case ext = File.extname(filename) when '.stm' SingleTapeMachine when '.mtm' MultiTapeMachine else raise "unknown turing machine suffix: #{ext}, use .stm or .mtm" end tm = machine_type.new(File.read(filename)) print tm.to_graphviz tins-1.1.0/examples/subtract.reg0000644000004100000410000000047412321542746016675 0ustar www-datawww-data# vim: set filetype=ruby: # Subtraction A = A - B, A >= 0 and A >= B register.A = 10 # register names have to be uppercase register.B = 3 label(Sub_B) { decrement B, Stop, Sub_A } # labels have to be uppercase as well label(Sub_A) { decrement A, Stop, Sub_B } label(Stop) { halt } tins-1.1.0/examples/length_difference.png0000644000004100000410000011167412321542746020515 0ustar www-datawww-dataPNG  IHDR|4*bKGD IDATxw\3[MJ56JQQ * +ƨk&A7YM#1Xbcl[ (D myܽHٝ3|{YgyfBP ` w`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA`Q:FA .\x5U< t[l]B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B( t0 B(B.]k.)))ѣm~,Y28UVK&9::2_.Mjj ˝5ksRPPuV~=H8:B0dRy<ޜ9sp+//۷o7₱*0DFFr\A 0G@̘1C.+p8X`322p8666`TDD A:Q!P(t `TnFI ]B0mΜ9 bݺu] @7} H&<~x `۶m;xzBB(p0܅@O˵/'AKo{:FA`Q:FA`Q:FA`Q:FA(SPP}3guUěCBBN>M_Pm%@ɓ'{I_U[[̗}=x>ضm=E `@ (Ya\4rСC{#c@&@zB t/++C 06:uWZeooqFܵA&uk,}}CY@@Q(K,A.BKLLˉ'֯_@ .;v "::֭[ԃxↆ3f.P BP.%%jhhx"3g/ݻ7k֬ VM;otl+ (cddݷmk``zԨQ&M:z(y5bĈ#G9rUC:2ꫂr9eQ "FMpy`Q:FA`Q:FA`Q:FA`Q:FA`端ںuk_P455|jsss_4k/ʕ+=zԥܽ{cƌr*̙3*׭[׭[7B(!!a{9sj-[nŊpJ_W{y.]r 233 xc( t@UWW2.%%Sݓ'O\;w޶G 2]##""$ɁI'O d2蚯Ӈѣ:V?N]p5klذaСj6ɯe2۷?v@=YyyyC 6mږ-[o- \.o߾7n܀;;ZBtJmm lM*444'Ǝf t/^=zTAݹsux/BA耎[ vvv4xORiVVVrr2%:p>,&&& 6/_y<ի: `'SPP0x]vQج[~~oVV)<`VuuuA\xАfuP(|>AMMM䇐yxx$%%Qx86x geeQzzz...'Oζiz:m%KN<9zhZt)SH$ZXamHKKDN@ P(th,,,lҤI?8P(D2p,: ӦMܹs'33ufnncn$7|'411a:vܹiӦ#Gxzz2y\@; %++룏>ZjդI>P(+BŋSN1bė_~ѡS td|>2ccc# ttWUUɓ vZܵ '''%###ܾ*Bz:: `An_uyܵ @ ]`tt}ƍ߾*0TGw@蜼ٳgϟ?kPX\\,qh[jkkLҧOw-oeee ! "22ŋ -}YWXBG[رcj* Cxz+N>vZܵP=-$J}~A~AA̙3#"">c`hϧ]|ygʔ)Bp͸Kk:Z~xR4))O>/))|* /BGH$#GHRPSSSIIIII'|B>b3@PTTP(Ytd2LwEGGd2uH ={ w!^:fmvWWW3_R'X:BG;v\.?+$O͵V?nN Yf}gY<z:Zn$kݻw r{}aÆa`.xYjjjk+>;w?ql=Am6wwwUu@ ~:*=C{x;w}ւUl̬[np[Gk)@' 8k?nkk<66UKEEEmmszںuj4jAٚU() thaCCׯ5 !iӦNhזFFFAAAoUl 6b:;r}||lmmcccB4z5Qڷ O͵v9n8k777B F t6BGAnРA\.!rkV߸q#5Qڷ) ) v- .\iii|?tМ"|]"r9 J:Ϗݳg /W(K,AR]e|$r| \ai%444\2 @Fbbb\\\N8~z k%o!diiijj CD"ʕ+B BFwADtt[MKV:Lضmٳg7 rɑ,* ZxqCCÌ3ꨭSMM thx\ \ f͚6_pE3g466^dݻwo֬Ys"6mv,奭 th7uT2,8Ό3 6_k``3jԨ0"ȑ#NNNTey]Kyi+˜vxRedPP\.W,9̺5@PZZ*Jyyw!J:`,^OOnh^z:ZB >:੹} tWo[Wh"j@"<w!2:?}tB LLLpV>dҽ/RYYzjZ҂rrvrppr?@TZZ: >Ro,a9\.KIGKA0- e2X,Rf!h:y{{7 ~qY`a8p`@7K`)/MᆱG~p<=='M$ 5Ea Nޒ4@ (** *ߟLhxx84P(lhhx)B t0puuEzj\%aZvvvvvvPPB2""wEޞýdÜc\r!m``. r!t4N:XVVo߾}IRБ#GOixj th$Jwݷo߱cǚݼy3<<<<<޽{iiicƌ۷ݻO5-ׯ_>wܞ={'%%X+gذaIII/^ٳܹsׯ____f 5P6&&G\.7""͛y͛7#""\n=bbbjkkSرw@E:VVV|>?***??-EEE|+++X\YYIGZ 55!s܅U@PL$DǏǏE"H$*//Nz*B* tR\\,bӧOjӧbX$Sղhllr]P>>wdKc@ ]2VbTeOO9s8;;edd5 w]m5jԥKҜ̙e]`i0wYD" B BCC_~zhh(AB066V"ஈFuuuA=zw! t Z,x[nuGm۶mƌU i]t-rX,iQ;ҼܹC߁lmmׯ_O_&: S"H S$//Юv%ə3gW|hΝ666WB/ƕwUUUEGG#|||;СC>9aH$ߦjW_uiD"###rWYY vh͚5r\Pz !dmmM߱O>uT4)**׷Ϟ=eBԢgϞb rOQQ%ͶI٥z;g}6p@4ѭɉݻwcT?lذ.!jFUWWXZZ oi̙\v?leeE!t%t9}ӧO˔WHNrppp8׮] b䛊hhh W^>ΥK pwwB˫<<55!'P۸ҝ;wB> tə0aA={_>tjjjrrr֯_okkkaaNCSWWyfr\ĉ)_7c!jUA?~M9t>3CfHՍ/R~OmΟ?occJ6׽{͛7>6OoA``2+!t}P( $ jANӧ6`i"mrV+W¼4bVdvv6ݔ#w LKK# |.˗B-`,Ŝ4򎲋Kll,x$Irrr~~~mܹs RӧO<(ؿ?*XqZZ+ WW)S<|077XA,_חt(tH7n &9;;S8+4 |)SΟ?OIaXgggr7l onҥFFFܴiL&@.MvlsCsNDDdz/_]]^|)ɹZѣA.t@$EGGWTTஈJfff"wEԻqB6,::'ODGGDD95::ɓ'+˗/BO]<\,w֍a*77wE%w֭X,օwͷlق :oxyoy}uֽ{ȹvvv3#W]mSSe˖gϞӧτ pr}={~]l)BhfPK IDAT6/[,??Ν>D(Yݵ֬Y# k%$$丸 2d˖-B8;;COG(%i\S媵S^^.LMM [OJbDDDh]2vعst>}*̌:X$O7-,,|||=zDE?1b*@gAPehhHΥxa^x!>|د_ݻ:u5ط~₻ Y:8qA+W#Gܻwݽ{744WMM {,۷oϗJ CcǾ{ >..ɉʕ+/dff999ũvj\\u:ud@!ݿ G*"H6l@Fϔ)SLp7lؠഴ4;;;77[nٔ*--Eѱ3,Ya{ݻ)kӧ#F044ܹs'Umj\n``g܅NQ]LLL֮]p1MMM(ZNf'ww wS`p v܉?>x111{GY^^px\s C%\iӦH ,̘1#+++55K X@h*?~ѣG˖-(ěZ^zeff~}lA tnܸq /&$$|WW9sfmm-P($.t BkZmo۷E"B4:hР㮈^ӧ С͛===Ǎyw}}}> B:Ԩܽ{EضçMrJL"Z888| tc7o<܅A__?..n׮]6l=zgpWD=.=:mKLiӦ9syYǏ4ʕ+ˡ<5:HJJ*..^t)B:s޽{nݺw9 46l0fwww܅t{'OFFFᮈ2:uٳgQ"'&&;vlذaZ;:ڴiS^>܅t\"J tiP@(~w!:jسgϒ%K3233'N8nܸ5kr6:jٶmޜ9sp";vl޼o d\5 tT'J7op&.?=͛7oԨQ ^HHHfffEEŠA]4, tTӽ{~G ˗4hA@PUUU]]Ul۶$22w!4255=xڵk͚5K#$AtYSSw-"bٲe)))gΜ]QA:,eӧOIygeee 0ȑ#i a9.۸qĉɞptt %NlܸqРAÇ]{EEE߼yԜ t:VZZ;T6hР,r*z:,ӱ8KK3f.DXYYZ~B t:P__믿.X@__w-=zFz z : BZhB4ĉ\B.?x%&- Eqq1Bxeiiу޷o9vSN]  drKy)X = &333AGedd.JX>O.?A̶ṉ@WAO r!P(*++wMW_}'UeAf:on.MMM ӣG4hPbb"4Z``rG}86yCeeeJRЍ72 .,Zhʔ)t/?` AIIIDf~ƍ'LK`:\.f4k֬ Z3.yCee%τ$$$t~wUUU 0`…/d2YiizeZ@輡kX͛CBBԣ5k,X@B1c͛7lr)':wm濺m;vС/"99Y.s89s樼Ja'] +W̟??>>5˗/ϧ83^n;vlFFF]]kL/_\zjm\XXι`ȼgώ5 !dooOP(ܼys]]̙rB\.722R.cV\vM__A TkpРANNNkNT*߿?B/99YPD"ݻ⊊ BnCCuׯ===[MxoCn nfaaH$222211D!___D`s\ru\V@Ǵ6t$Ill@ "44gbAfffٌ >vZP\GEEQ@0tb Nj}v'_X]]b KKK>Ckt??? Z_aYm_S\t5*t***bq D"ѣGThױ'888++:AkcǎWp87onp5NiiH$211122Dj6NDppK(tqqqAx<q##bkͧSTToaa!={Fa㍍B( 11Arss>}WX>εй~DDϷ}MdlODä{-Y\ѱGp5FNVVVpp0qpp}53MKK{BJW5?}k-as%rH{||<{iiiBFkpƄNbbb@@Bw9xL&[ύ7"""8@ s:r>>>'&&b6w툈gcc#pW\9_~#G<="EGGԞsS:... 6{IttrjOii)4kĮ!'8;;s܈7nந˞?"E}}=NYl /_bkkkr͝;wBAAAHHۺu:?dCCCwwsfffv ҫWbccmmmɩ=W6G 84&Ċh333rMAA <ֶ)66H$gΜ!_˺;wp8]zHGGGrjիWUn/^ %k\ӧB%%%I4O},,,._LGiii#GDDa&Mj~㣏>bx"h= Ça:IOO'=<<D_®~Q+wޥH9 X*dEEE۷o'ׅ@mܸ;mh: "44t޽zpD{g&u֭ 333SByjjjrrr֯_okkkaaNCoHKK;v,yC–'Nzw(lm\ws}U')Cf{ B.zW\INTH$:tPUUH$IR [=B(??f纫(9+WoZv [^^^TTdz􍎍0arŋm?ZU9fС4k@ 6n}k1W\AAH$244455DԶuVwwwrL&ۺuw_T#z.L.tO8JNNFZCZs!1]ӧObH$Fzz^kΝ;G@*>}>J理Bbcc{IoygXXXAAjkk8P\3pi9S[nzzzo-#8NO_PPPm5SL9)уxMZnmʕzzzz/n sNjjjbcc8Nhh(,qVVV|>?***//wEJs>..ɉ)d_*//D"Us l됧'B( %%wEj)..Dbӧ+b8:-C" 8w:r~X,ң\Zg+tHr<11!)ݽ{744HAl %C}cU233i5NNNqqq+oee%++++DN!kOMs[aC ȩ=eee | -B06T<~4.ϵƥ)4,td2ٚ5k\nhhh^^X,677'TCP($"44r|̘1\.Rƅ\t ]ISRR2|p##xcbb,--ɩ=ž<׀*4GGG@¿cԞANLQNݻ:q8ղ ;׀ _~?BBo=ڵkM*Oټys;|>ۻTAW1pX: B"̘1P5K95..{777wh &#055򲳳!k\? @n\} 2___ 'NPٳgɭlll >7odϭ#wSSSrb1 g\ۓ䧟~]`Ydgg BWW۷ow==QFڵA4IIIApܐ􂃃 Eff%Ks=t˗)tN8ajj:rH5o⴯ !t!:_jՐ!C?YYY={tssx͚5kĉ4yk֬?~9sOKKK$HBt47dffZYY5322 q\nnnyyyHҨ/~ڸqM122(-ڦ,X 44R;ѣGL} Ѵ̨3gNbbݻg͚ di鴃C {nח9::EzjرɧOf&q!M>̙3/^/**RrssCvBѣG.] dX.p8~~~W^U155]:Çd/^$'0oOx…ݻc%ڭ:a۷o>G  211?"###""6oތ؀w=z۱c,,,>:BH"p\Ϗ[xqEE"ziU:FC#Gӧϱcp5jkk Mk֬qqq?~~~mY.؀+W>rGlqIO~mBddyxxxUU \-Nzo ۫Wȉr=+WÇg,qPJ$BhҤI'O<{qjjjpZߺ"xj=nܸ߿yZv{wSSSܹ{=w9=trrrF흘Ȇ,R8p`JJJiiiHHׯq8NϞ=#G;))%oyyԿ3g?|=h O=֖=X|y;拉=﨣͉ ;B&88:ǔ͗WJgϞ}رc:Zpy-^\\Ķg,RHMMχܡϫqh ?0--ɓt_^)?ətݻw:tLJէWJ?vؕ+WfϞ OQB(x<(?OmTH$! :رc'NOqע |3iW\7oއ~((lZ! >;v̚5k<#{:/^ܰaƍY8mJiƌs΍zZ4l SSS1eʔHj v\^)ϮMMMk00#C>H$ Mk.HѸk0X:g\\ƍY>*ZlzEGG-[;v w-M*vXt9tϟ?m4xFނD"aT:uY.\˹wl QCocЉW矹\.ٲUXc?ӆ lmmi*Z bŊ]ׯ_ojj_9Nn|IZlϦv5jԨSN6 w9TTTobbsNrhУXExۼϞ=v˥& ZXXr \P(R)B(11q„ Xk󓒒޽˶%bYq999Hnp5_Sօ˫ǏlڴIS!dllCUhhرc,X@v@ |=S#H>ɉ(ЧO?7nmyyy7n+Vh\ccA::D"Yr%dԩzzz,XA7:mҥk֬] -_w:8t tޝ0q?dqCիW#bbbpF+Wl `w%mllo׺uqF_T~8NHHtH=Tw͙3G& K*j-/^_.);;pig޽{y<ޣG@8qB!am˖-qPWWףGxSNHtYnԩS{Ic1#z-XPb޼y={;;m200ЁȌj'222BE &L@Akaȯ_ZZ6'oE_|||?M2EP{**sε]7!̴QMMц hͼ^z^VVt¢w!׿L?[om>|\?˗3OM]]3x8coҥ}opBܵtك|}}.b֭]6o {͇3744, 3fl޼YC!}%=/^3\ ŋoݺz[$%%qܐt)%:#FuӢE>} 3_ -,,v؁ ̚\kFgϝ;_ms=3F;wY >.\XRR|X:.\иA\\\ƌv-CG.gff>K5V-:uTnn.BNk:>|,/Ǝk.܅2t_ׯ_?,Zqܹsڵ n'Zݻw=<\SSZNAA R3e2١Cpt#HpUDh"kkkKKŋ744t999~5W( &M 9~t-88Xwh#Gu}̙%%%+<{ !|( HMM%bȑ/_ܻwo'_)pe˖6wIɓ'¸su>!aÆfgg.x!dmm.pBRRҒ%K߯_K۷ڵk|y}}=Q8 秦8qYYYi߽Q~bo?YPPn:uyBS1]FޘxoGڿ?ΚP(Mի{S&W(4ZZ !G?(8=:Ul?!J~K~|J@@@gt$''ԔUwʕe˖9::R3rssoݺEa,'$###$$VOO{l[o.B!:Nyy9B[nd픔dddxyy}7l{C^ۛv}}}>~Sl'D$]p!33իW۶m;p@TTMOoNSSBc*^|200 %㲲R iiiiii|rЦMhUU Dr…ׯ744޽[f 4iSUYY) &M:wwUg}×/_O!j;Ŕ`[a#?LRV" Iq\/B޽{T6ʕ+-,,z"~[4iҭ[=z~SE'jӦMB}O={_QQ1`3grP`` ڣ١RB Z# SE QΆ#?O>T堠 KKK J~CzzΝ;i*RM~iiiׯO?~x5?!VZv}y{{T$Uۗ2z蠠 ܵGC'""!J~={j]z!4}tBǎ#>Bh̘14>iҤ'OP ٶmB?D566R"EN<9o w}ɓ'4K+ ~SL<7Ay :tڴi}{l=pW H{:Ak˖-FFF(GaU}ut&LPWWיLPBG0hĈlh @#Fq9pAP(`@+,  !4bĈlr!hBhذa/.h?Bݺultq* ~?>uԼyvE"B\/;;w!B"ܹ׭[wersbmm CAS]]}ĉUV-\pEEE+oo7oB'888,]\D.*w9w\P}!tx{{CO1k׮ms&rti̡O.eB&&&xlUп\@dR/!!ؘ'&&у|3ɵI1+,,l~~~ X?+nnn2X7^_ĉ97&+FLJJd /abbafagpLQ$tɒ@{۶mV9-|VVV X[ٳ?#|7|?;kggBUX___ 7l_-Z: By|>fff^=**ի ܲe ) WX8::>| +W?ݻ˗?EM2ŋxxt0 { ?׏9|pZZڀ` xwqM]Ož*ą nQjZV՟uઢb*ֽ D@PCe>O BHn%7~3p9۷dW :.zѐ!C<<<|pSN]N7 t? "['&BHKK'AHOH!Xv@>>wss=rH aڵׯ_"CSlmmLgqQ\pB ,,,%%@ tWQQ葩SZ[[Bb#QrJt ߄SԄ֕ëg"Ə8n8P\\ bs!p3k֬KSSSM&fIII}!oW_}%Zs,ͱ0f777,++CIT|m;FݸqIGGGfǏ/m#HAu&cٲe?2:!===GfeݺuFFFx "!ϟ5k0L1qD\JNgʔ)Ǐ2:>}Bb?bKTWW󞐑`0mBXTT$G,^^^b4i$\N 7A e111="&á, /{X!˥hIMM4h$''[ZZJKPGGx ]Y`A]]ŋ{ NB>m۷8ڵk{űBܝ?~̙ⷓ$VH!&t`ԩ! 6˗/>}3fMihh?~BөD\ŋ?SUUCEzt 7+ .LNN.--~ Э[(D_ߟdU$rssutt,--l'--B}?OEzt 7SӧO/bbbzNۛvd@.ݷoϟpMMM\.~YfyF䪸ȳvڟ~Iv.\,~;&:z~s`cccRRRhnwo.֬Ycjjf|lNCC7|ӷo˗׷}ã-OMMݺ"rU\ɄUnnoӦMC19{ؙ&ࢨB$'' [md.tԾ'O .D(.@:{]...s:@7oիم|…Za XǏ| .dd2ҦLBv!@7ܹs<BGܹsdN:B={͛7kjj}&ILS{ IDATL166& f͚f\3!t͛7 HH>}Ǝ+(++{1ٳg_~kX:"11QUUU{?͞=b]vM tEbbمBp8III'O& f͚u zA(NI򪯯hdddkkKv!@ΙXZZ BG!ܼysr<'NLNNW[[ V&Lw!t_jj*Ñ0aB(55'@ȿ7o9wd#ցБpl$t*%%HBIIIqqޡŋ#G]^x ,&Lm۶W^v|бBHKKΎ*Bիd" P _`` %HjzzzC9>>Ϗ8m׮]6mz6ٵ(..B/B(>>B䄫Ç;>tBh,K~3+**222ğ=z46VG:!Իwooo?Bpvee対BqppxQCCCLJ t+444???//BtI&ijj]P8l6;??C:>dȐ( MmmmJJ [RXXX=|C:ZdӧG%&&Xӧ]PPvvv=B_rم̙3d]AAA:՝3gNdNyy /^Lv!@q 2oi'44K}2ɓdmmmmyy9rv\\\ &맓\cTUUɮ(. C[xq\\ܧO.DtϞ=[d مf``QRR·B߼yTLN1bСC.(4 2p@uuugϞ]`م PZZʷBd"Gl dqYYBN=zĈx:e݋/իٵ !t `pi_YYwߑ]!ddd;: 鱱d\.t$g``P__v!N455Ν{ak֬!KOO!TSSv!N-[VTTt ֮]GEv!N~ɍ7VZEv! BBCCϞ=[UUEv!۰aȑ#a UB|@ﯦ&.\a PSSSۅ:9rDO'oٲӓBhGYY!v!N7BCC矴4 Rnnŋ7nHv!hT*Bn :YO'o޼|҉NCXhh{ ă\~z s,F]=___MM͘ իlZfcgvx t6o޼(Cv-;w.55u߾} Zv`E.ҥK_xqm Wss?8w\GGGksu+͘1ct+**~7 K!mm !tz…CۓǏ7o 366&u:C@GWWWJN'o޼YUU.Z)##G~:ׯ: Ё+хz*992.]joo|rr[:h{:wΜ9sRiWVVfhhwKYȨРo>}СC/_L&ԬZjɒ%0R׭[Phh(m455IO.-gggUUU;;ϟ?ST˦&b&_lmؖ{فCv…Ç'@yi.PX,VBBرc̚>QnF}m߾wiĈ `٭@իW&&&| !t뛑rY,ߣY|aN͛7} N "S\\laaBG(ÇWRR7Iy޽X8@Q00E?}dnnηB9tдi:KJJ6lO?YYYItCƆo!B2d5)%ɓ鈈J 6ܑ]dڵk%5|%vSh4Zpp0Yȓϟ+++9ѩ]vظcH4tbbbܹpf.ad#Omll:@@>}455ێFR%:>|Xf͊+ &M(8ѣGΔQTGG[|(((:th:=cnn~M:λɒFI.t.\e BOB^ :.1xTr{:QQQ׮];y򤺺$?|𡬬ֶC:#}}l6=={8qHڜ9st:N={6ٵȉѣGw]\x1"czzz&M¥ALAAA5|p92#f[dooob6rӧ-q{O>Ji;Kw||-&5JB.ۣe޼ys]9|}}.g؋'Iy#ĉmfdd0n.8::u55)TjTTANNN~~~kk+I|R 77[!DFF}!dllZlB())H%Ν;Ӛ:=vر۷oR(-xDX<<>BHjjqRSS6C4pNйyҤI&R+0._u tl}||F{㰧wB =@;o߾W^mcc#!t\R__?""BB_/^oܸ!Dz€=~~~SLV t^SSsNn!;wX=*--o-Z-mAlvPP޽{ ^mۖ%VB=Zvv͛7n8bb*//'l:(iӦ;wNI3-pNիwjii]O:u9+++7 W(ׯ^:""b֬YoB`0fϞ|r# Bk.j@QN6166J%wB3f+..NYYJ򯦦fʔ)YYYzzzĉkkk322$=l0 tgXԤ]B:ȱZOO߾}[JdUuu)SJKKoݺ5h r!//A o=z_]?JffСCH:)Dž Lzybrb׮]gϞ1cƹs.KpԴ`ݻw\r˗/9B7Jnni j̙>LHH `*AEѪ\n6449lȞ?>k֬ʛ7o]PPP&&&cƌt*ڿ+W=ZYY9''GVAE$CҀb\rƌYYY2qO{:4mΜ9#ooCEFFFEE]Q@ť7ydv!F|TVVv) EGt:?dWlC\]])q!??V???kAEEEnnn+W OOO "AƎ?vXhiiYvy dWOAECh4󟖖R5jԁ<9x`R P\L&sK,qqqqqqYdL&ae455mڴՕNgff88m9so rÇڪaaa/_Ė|2,,LUUU[[;<<Ǐի{immP,o߾ TWWpuuuMMͰoJS԰0Mz@E eee==*ϯSVV z9^0p:>jԨ\:@=}4((NFFF nmmmdd!N z\zuڑ r<BȳӧSTcczک466RӧOm, !+*:@>eddL8!4hРflnn8qbff+//_ͥKƌ1bĥKl6x>1c\tIoޫW/CCØ܋E:@N옘aÆ!/]p$9s%GGGаa6pbbbLLLo.25&&!4}tA vgkkNMMuppPRR 22dFFFQ(ӧ߹sJ )#B0a;}t\m Wcc;V^˗/crHzʪ'\*ھxӧOJJJ!!!dWį8$$DIII__?""ӧOdW$] t(// RSSkaJ:aݸԴɮHZ@͛0 J+VeeeDDq ՞={uիWDDćȮH|ݸ={FvEdRɓ'شX:yűc _O555KK dggPER}||Sލ/_Μ9SGGb BHlTDnޞ7k566`k}d~?۷/J믿D655EEEƕ#Nk=ջQUUe``6d###%W"eo++\itVbb"BhРA◄]S3fLrrm ڰa˱-,,$X@ t).X܌9Sx6^K.1Dk0_-ǏB+ndb'N>|3\OOO 3f[V)..F8d:Jrvƌ#F8qk?MF@rX'Nϟ? #++S:'ꮯOJJ;wmBxzzfee1 cc۟8q7ٱ5Fa-B(88XkWX)SSSTFF.Zm 4ɓ' idd$ķ}ƍMMM%'BD7==-:\.h޽$MKK۷/B(<<ߖڒ7 VTTF:tH+B3txܹ9r$~ud؞3|hjj5j֭[\'ܹs!S @IIIXXJ>}"""%-B!_iTWWGDDGEE%,,D[ .q8nׯ_GHhc)--m+L[+t222B666_eeeٸJKKqOѣG---?rlѣG &`߿UQQ y5^-766&%%ukZL&355[˗,2>>~ %..\ׯCBBTTTtuu#""޿c|z7222Κ*ݶsssB/^YTT$~.:;;uJAIDAT{xxN722NKK*LQQ6W޽oNFW_J\vPAA6@^ú&ݻww=sY~D*څϟBׯ_'0 SؽQ2dF 8'_7. |yPP1O`B֭[NNN!Ǐ X622NURaa!a 22G'{ ݂x]r7n\VV׷ƕ'N1X)ccH)::`kk?\ |BXg#G&%%֍!4qD3'33}a``%1a]LL –!&L`0$T"UV }777nPb2tnn iMMM۷on#O:pԩƥ(ܮ0aĺ.[VTTZjd;d PX`ɓ' (.0te˖M2ٳg% 2݄Nccٳg ('''??!C|JvQLݏ_xj<)++ q8u-[TUU\~ӧE%ll;;aÆ:uJ5YrϞ=q '( =GѶlLBBvc1${:iӦh4\ZZ333}||6l؀ zvsO<9zR&M;v,NȈ=ճб^tMjjj$TNϟ?5jTuuuRRRjj E"""8κu$Q B^ 2dH~~3gx N޽|...f!. GD]yϞ=JJJwf Z[[?|@vE@>xxӧO󵴴B@$lm۶-]t͚5d P(Ǐ7668Xlٲɓ'?{%'}ݻwѣG]WA0ovvv/^Ɂ)v߾}{BB. UTTܻw/..pc1 ^ -Zɓ'&&&x5 ۷8p@[[{pc1ߧͅˮ䪫۵k9ڵkWXAvQ o \\\ L@]v555}aaaz"(s ^|8v3g"a7_eeUV^OvQ333s]xqǎ7:r-[6ugϞm߾H'Loׯ_Dd'''???[[[ltKuʕ_9s222$ `0\]]'M}x H? N/}᯾/˓VÇ'MNR FRRѣ. H0th4ɓ']\\BG$i9V\\;r>$%%]= A)++߃ >> i*B֭Qmɟ>}MC9sFszc͛6m搨EE$DztDMa|رfZr]=%iW>aaa؁^uuʁȮU<|L0̙3dW$Azzz!~Ǐ]BЉ FX!O:,`xl0l3g͛0`@nnnNN-33֭[FFF?=Q>'))iFFF!*l2;;***ƍ۽{7Bĉd@gؤ$]vU1&O.c dcO[IIIuuumw#G]tА!C.I8qbڴimblv-XNRIݻwB| م= &`00LPSSSfffۅ=ںuߍ9o޼YlYUUB1%%{=f9''gΜ9CmzKKKVVT1-,,fϞիW,\1nCɝqcW/ϟ?>566v[0w$wUƷ~>rlDIdй#| bNطo߾}.I@.A P:BA P:BA P:BA P:B9r/a@[EBBBhh(YHU (R20@A9 t B@>82̟IENDB`tins-1.1.0/examples/ones_difference_19.mtm0000644000004100000410000000051312321542746020507 0ustar www-datawww-data# vim: ts=2 sw=2 et ft=ruby # Call with two strings of ones on the tape: # $ turing.rb ones_difference.mtm 1111 11 0. right 1, goto: 1 1. right 2, goto: 2 2. cond 1, if: '1', then: 3, else: 4 3. cond 2, if: '1', then: 0, else: 5 4. cond 2, if: '1', then: 5, else: 7 5. write 0, symbol: '1', goto: 6 6. left 0, goto: 0 7. halt tins-1.1.0/examples/null_pattern.rb0000755000004100000410000000150712321542746017404 0ustar www-datawww-datarequire 'tins' $:.unshift 'examples' include Tins::Deflect puts "Example 1" deflect(NilClass, :method_missing, Deflector.new { nil }) do begin p "foo".bar.baz rescue NoMethodError p "caught 1" end p nil.bar.baz t = Thread.new do begin p nil.bar.baz rescue NoMethodError p "caught 2" end end t.join if t.alive? p nil.bar.baz end begin p nil.bar.baz rescue NoMethodError p "caught 3" end puts "-" * 70, "Example 2" deflect_start(NilClass, :method_missing, Deflector.new { nil }) begin p "foo".bar.baz rescue NoMethodError p "caught 1" end p nil.bar.baz t = Thread.new do begin p nil.bar.baz rescue NoMethodError p "caught 2" end end t.join if t.alive? p nil.bar.baz deflect_stop(NilClass, :method_missing) begin p nil.bar.baz rescue NoMethodError p "caught 3" end tins-1.1.0/examples/turing.rb0000755000004100000410000001604712321542746016212 0ustar www-datawww-datarequire 'term/ansicolor' require 'tins' module Turing class Tape def initialize(*initials) @left = [] @head = 'B' @right = [] c = 0 first = true for initial in initials if first c += 1 first = false else @left.push 'B' c += 1 end for s in initial.split(//) @left.push s c += 1 end end c.times { left } end def read @head end def write(symbol) @head = symbol self end def left @right.push @head @head = @left.pop || 'B' self end def right @left.push @head @head = @right.pop || 'B' self end def clear @left.clear @right.clear @head = 'B' self end def to_s "#{@left.join}#{Term::ANSIColor.red(@head)}#{@right.join.reverse}" end alias inspect to_s end module States class State attr_accessor :tape end class Cond < State def initialize(opts = {}) @if, @then, @else = opts.values_at :if, :then, :else end def execute tape.read == @if ? @then : @else end def to_s "if #@if then #@then else #@else" end def to_graphviz(stateno, tapeno = nil) %{#{stateno} [ shape=diamond label="#{tapeno && "#{tapeno}: "}#@if" ]; #{stateno} -> #@then [ taillabel="+" ]; #{stateno} -> #@else [ taillabel="-" ]; #{stateno} -> #{stateno} [ label="#{stateno}" weight=4.0 color=transparent ];} end end class Left < State def initialize(opts = {}) @goto = opts[:goto] end def execute tape.left @goto end def to_s "left, goto #@goto" end def to_graphviz(stateno, tapeno = nil) %{#{stateno} [ shape=rect label="#{tapeno && "#{tapeno}: "}L" ]; #{stateno} -> #@goto; #{stateno} -> #{stateno} [ label="#{stateno}" weight=4.0 color=transparent ];} end end class Right < State def initialize(opts = {}) @goto = opts[:goto] end def execute tape.right @goto end def to_s "right, goto #@goto" end def to_graphviz(stateno, tapeno = nil) %{#{stateno} [ shape=rect label="#{tapeno && "#{tapeno}: "}R" ]; #{stateno} -> #@goto; #{stateno} -> #{stateno} [ label="#{stateno}" weight=4.0 color=transparent ];} end end class Write < State def initialize(opts = {}) @symbol, @goto = opts.values_at :symbol, :goto end def execute tape.write @symbol @goto end def to_s "write #@symbol, goto #@goto" end def to_graphviz(stateno, tapeno = nil) %{#{stateno} [ shape=rect label="#{tapeno && "#{tapeno}: "}#@symbol" ]; #{stateno} -> #@goto; #{stateno} -> #{stateno} [ label="#{stateno}" weight=4.0 color=transparent ];} end end class Halt < State def initialize(opts = {}) end def execute -1 end def to_s 'halt' end def to_graphviz(stateno, tapeno = nil) %{#{stateno} [ shape=rect label="HALT" ]; #{stateno} -> #{stateno} [ label="#{stateno}" weight=4.0 color=transparent ];} end end end class BaseMachine def initialize(program = nil, &block) @states = [] if program block_given? and raise "use either program source string or a block" interpret program else instance_eval(&block) end end def step(*tapes) @stepping = true run(*tapes) end end class SingleTapeMachine < BaseMachine include Tins::Deflect include Tins::Interpreter def initialize(program = nil) deflector = Deflector.new do |number, id, name, *args| opts = Hash === args.last ? args.pop : {} state = States.const_get(name.to_s.capitalize).new(opts) @states[number] = state end deflect_start(Integer, :method_missing, deflector) super ensure deflect_stop(Integer, :method_missing) if deflect?(Integer, :method_missing) end def run(*tape) @tape = Tape.new(*tape) @states.each { |s| s and s.tape = @tape } goto_state = -1 @states.any? { |s| goto_state += 1; s } begin printf "%3u: %s", goto_state, @tape @stepping ? STDIN.gets : puts goto_state = @states[goto_state].execute end until goto_state < 0 end def to_s result = '' @states.each_with_index do |state, i| result << "%3u. %s\n" % [ i, state ] end result end def to_graphviz result = "digraph {\n" start_edge = false @states.each_with_index do |state, stateno| state or next unless start_edge result << "start [ fontcolor=transparent color=transparent ];" result << "start -> #{stateno};" start_edge = true end result << state.to_graphviz(stateno) << "\n" end result << "}\n" end end class MultiTapeMachine < BaseMachine include Tins::Deflect include Tins::Interpreter def initialize(program = nil) deflector = Deflector.new do |number, id, name, *args| opts = Hash === args.last ? args.pop : {} tape, = *args state = States.const_get(name.to_s.capitalize).new(opts) @states[number] = [ tape, state ] end deflect_start(Integer, :method_missing, deflector) super ensure deflect_stop(Integer, :method_missing) if deflect?(Integer, :method_missing) end def run(*tapes) tapes.unshift '' @tapes = tapes.map { |tape| Tape.new(tape) } goto_state = -1 @states.any? { |s| goto_state += 1; s } begin printf "%3u: %s", goto_state, @tapes * ' ' @stepping ? STDIN.gets : puts tape, state = @states[goto_state] state.tape = tape ? @tapes[tape] : nil goto_state = state.execute end until goto_state < 0 end def to_s result = '' @states.each_with_index do |(tape, state), i| result << "%3u. %1u: %s\n" % [ i, tape, state ] end result end def to_graphviz result = "digraph {\n" start_edge = false @states.each_with_index do |(tapeno,state), stateno| state or next unless start_edge result << "start [ fontcolor=transparent color=transparent ];" result << "start -> #{stateno};" start_edge = true end result << state.to_graphviz(stateno, tapeno) << "\n" end result << "}\n" end end end if $0 == __FILE__ and ARGV.any? include Turing filename, *tapes = ARGV machine_type = case ext = File.extname(filename) when '.stm' SingleTapeMachine when '.mtm' MultiTapeMachine else raise "unknown turing machine suffix: #{ext}, use .stm or .mtm" end tm = machine_type.new(File.read(filename)) $DEBUG ? tm.step(*tapes) : tm.run(*tapes) end tins-1.1.0/examples/recipe.rb0000755000004100000410000000304112321542746016137 0ustar www-datawww-data#!/usr/bin/env ruby require 'tins/xt' $:.unshift 'examples' require 'recipe_common' class Cup < Unit; end class Teaspoon < Unit; end class Tablespoon < Unit; end class Flour < Ingredient; end class Bakingpowder < Ingredient; end class Salt < Ingredient; end class Egg < Ingredient; end class Milk < Ingredient; end class Butter < Ingredient; end class Recipe < Tins::BlankSlate.with(:respond_to?, :instance_exec, :inspect, /^deflect/) include Tins::Deflect def initialize(&block) @ingredients = [] deflector = Deflector.new do |number, id, name| if unit = Unit.unit(name, number) unit else ingredient = Ingredient.ingredient(name, number) @ingredients << ingredient end end deflect(Numeric, :method_missing, deflector) do instance_exec(&block) end end attr_reader :ingredients def to_a @ingredients end alias to_ary to_a def to_s to_a * "\n" end alias inspect to_s def method_missing(name, *args) name = name.to_s.gsub(/_/, '').capitalize @ingredients << Object.const_get(name).new(*args) end end class RecipeInterpreter def recipe(&block) Recipe.new(&block) end end recipe_source = <M_Pm%@ɓ'{I_U[[̗}=x>ضm=E `@ (Ya\4rСC{#c@&@zB t/++C 06:uWZeooqFܵA&uk,}}CY@@Q(K,A.BKLLˉ'֯_@ .;v "::֭[ԃxↆ3f.P BP.%%jhhx"3g/ݻ7k֬ VM;otl+ (cddݷmk``zԨQ&M:z(y5bĈ#G9rUC:2ꫂr9eQ "FMpy`Q:FA`Q:FA`Q:FA`Q:FA`端ںuk_P455|jsss_4k/ʕ+=zԥܽ{cƌr*̙3*׭[׭[7B(!!a{9sj-[nŊpJ_W{y.]r 233 xc( t@UWW2.%%Sݓ'O\;w޶G 2]##""$ɁI'O d2蚯Ӈѣ:V?N]p5klذaСj6ɯe2۷?v@=YyyyC 6mږ-[o- \.o߾7n܀;;ZBtJmm lM*444'Ǝf t/^=zTAݹsux/BA耎[ vvv4xORiVVVrr2%:p>,&&& 6/_y<ի: `'SPP0x]vQج[~~oVV)<`VuuuA\xАfuP(|>AMMM䇐yxx$%%Qx86x geeQzzz...'Oζiz:m%KN<9zhZt)SH$ZXamHKKDN@ P(th,,,lҤI?8P(D2p,: ӦMܹs'33ufnncn$7|'411a:vܹiӦ#Gxzz2y\@; %++룏>ZjդI>P(+BŋSN1bė_~ѡS td|>2ccc# ttWUUɓ vZܵ '''%###ܾ*Bz:: `An_uyܵ @ ]`tt}ƍ߾*0TGw@蜼ٳgϟ?kPX\\,qh[jkkLҧOw-oeee ! "22ŋ -}YWXBG[رcj* Cxz+N>vZܵP=-$J}~A~AA̙3#"">c`hϧ]|ygʔ)Bp͸Kk:Z~xR4))O>/))|* /BGH$#GHRPSSSIIIII'|B>b3@PTTP(Ytd2LwEGGd2uH ={ w!^:fmvWWW3_R'X:BG;v\.?+$O͵V?nN Yf}gY<z:Zn$kݻw r{}aÆa`.xYjjjk+>;w?ql=Am6wwwUu@ ~:*=C{x;w}ւUl̬[np[Gk)@' 8k?nkk<66UKEEEmmszںuj4jAٚU() thaCCׯ5 !iӦNhזFFFAAAoUl 6b:;r}||lmmcccB4z5Qڷ O͵v9n8k777B F t6BGAnРA\.!rkV߸q#5Qڷ) ) v- .\iii|?tМ"|]"r9 J:Ϗݳg /W(K,AR]e|$r| \ai%444\2 @Fbbb\\\N8~z k%o!diiijj CD"ʕ+B BFwADtt[MKV:Lضmٳg7 rɑ,* ZxqCCÌ3ꨭSMM thx\ \ f͚6_pE3g466^dݻwo֬Ys"6mv,奭 th7uT2,8Ό3 6_k``3jԨ0"ȑ#NNNTey]Kyi+˜vxRedPP\.W,9̺5@PZZ*Jyyw!J:`,^OOnh^z:ZB >:੹} tWo[Wh"j@"<w!2:?}tB LLLpV>dҽ/RYYzjZ҂rrvrppr?@TZZ: >Ro,a9\.KIGKA0- e2X,Rf!h:y{{7 ~qY`a8p`@7K`)/MᆱG~p<=='M$ 5Ea Nޒ4@ (** *ߟLhxx84P(lhhx)B t0puuEzj\%aZvvvvvvPPB2""wEޞýdÜc\r!m``. r!t4N:XVVo߾}IRБ#GOixj th$Jwݷo߱cǚݼy3<<<<<޽{iiicƌ۷ݻO5-ׯ_>wܞ={'%%X+gذaIII/^ٳܹsׯ____f 5P6&&G\.7""͛y͛7#""\n=bbbjkkSرw@E:VVV|>?***??-EEE|+++X\YYIGZ 55!s܅U@PL$DǏǏE"H$*//Nz*B* tR\\,bӧOjӧbX$Sղhllr]P>>wdKc@ ]2VbTeOO9s8;;edd5 w]m5jԥKҜ̙e]`i0wYD" B BCC_~zhh(AB066V"ஈFuuuA=zw! t Z,x[nuGm۶mƌU i]t-rX,iQ;ҼܹC߁lmmׯ_O_&: S"H S$//Юv%ə3gW|hΝ666WB/ƕwUUUEGG#|||;СC>9aH$ߦjW_uiD"###rWYY vh͚5r\Pz !dmmM߱O>uT4)**׷Ϟ=eBԢgϞb rOQQ%ͶI٥z;g}6p@4ѭɉݻwcT?lذ.!jFUWWXZZ oi̙\v?leeE!t%t9}ӧO˔WHNrppp8׮] b䛊hhh W^>ΥK pwwB˫<<55!'P۸ҝ;wB> tə0aA={_>tjjjrrr֯_okkkaaNCSWWyfr\ĉ)_7c!jUA?~M9t>3CfHՍ/R~OmΟ?occJ6׽{͛7>6OoA``2+!t}P( $ jANӧ6`i"mrV+W¼4bVdvv6ݔ#w LKK# |.˗B-`,Ŝ4򎲋Kll,x$Irrr~~~mܹs RӧO<(ؿ?*XqZZ+ WW)S<|077XA,_חt(tH7n &9;;S8+4 |)SΟ?OIaXgggr7l onҥFFFܴiL&@.MvlsCsNDDdz/_]]^|)ɹZѣA.t@$EGGWTTஈJfff"wEԻqB6,::'ODGGDD95::ɓ'+˗/BO]<\,w֍a*77wE%w֭X,օwͷlق :oxyoy}uֽ{ȹvvv3#W]mSSe˖gϞӧτ pr}={~]l)BhfPK IDAT6/[,??Ν>D(Yݵ֬Y# k%$$丸 2d˖-B8;;COG(%i\S媵S^^.LMM [OJbDDDh]2vعst>}*̌:X$O7-,,|||=zDE?1b*@gAPehhHΥxa^x!>|د_ݻ:u5ط~₻ Y:8qA+W#Gܻwݽ{744WMM {,۷oϗJ CcǾ{ >..ɉʕ+/dff999ũvj\\u:ud@!ݿ G*"H6l@Fϔ)SLp7lؠഴ4;;;77[nٔ*--Eѱ3,Ya{ݻ)kӧ#F044ܹs'Umj\n``g܅NQ]LLL֮]p1MMM(ZNf'ww wS`p v܉?>x111{GY^^px\s C%\iӦH ,̘1#+++55K X@h*?~ѣG˖-(ěZ^zeff~}lA tnܸq /&$$|WW9sfmm-P($.t BkZmo۷E"B4:hР㮈^ӧ С͛===Ǎyw}}}> B:Ԩܽ{EضçMrJL"Z888| tc7o<܅A__?..n׮]6l=zgpWD=.=:mKLiӦ9syYǏ4ʕ+ˡ<5:HJJ*..^t)B:s޽{nݺw9 46l0fwww܅t{'OFFFᮈ2:uٳgQ"'&&;vlذaZ;:ڴiS^>܅t\"J tiP@(~w!:jسgϒ%K3233'N8nܸ5kr6:jٶmޜ9sp";vl޼o d\5 tT'J7op&.?=͛7oԨQ ^HHHfffEEŠA]4, tTӽ{~G ˗4hA@PUUU]]Ul۶$22w!4255=xڵk͚5K#$AtYSSw-"bٲe)))gΜ]QA:,eӧOIygeee 0ȑ#i a9.۸qĉɞptt %NlܸqРAÇ]{EEE߼yԜ t:VZZ;T6hР,r*z:,ӱ8KK3f.DXYYZ~B t:P__믿.X@__w-=zFz z : BZhB4ĉ\B.?x%&- Eqq1Bxeiiу޷o9vSN]  drKy)X = &333AGedd.JX>O.?A̶ṉ@WAO r!P(*++wMW_}'UeAf:on.MMM ӣG4hPbb"4Z``rG}86yCeeeJRЍ72 .,Zhʔ)t/?` AIIIDf~ƍ'LK`:\.f4k֬ Z3.yCee%τ$$$t~wUUU 0`…/d2YiizeZ@輡kX͛CBBԣ5k,X@B1c͛7lr)':wm濺m;vС/"99Y.s89s樼Ja'] +W̟??>>5˗/ϧ83^n;vlFFF]]kL/_\zjm\XXι`ȼgώ5 !dooOP(ܼys]]̙rB\.722R.cV\vM__A TkpРANNNkNT*߿?B/99YPD"ݻ⊊ BnCCuׯ===[MxoCn nfaaH$222211D!___D`s\ru\V@Ǵ6t$Ill@ "44gbAfffٌ >vZP\GEEQ@0tb Nj}v'_X]]b KKK>Ckt??? Z_aYm_S\t5*t***bq D"ѣGThױ'888++:AkcǎWp87onp5NiiH$211122Dj6NDppK(tqqqAx<q##bkͧSTToaa!={Fa㍍B( 11Arss>}WX>εй~DDϷ}MdlODä{-Y\ѱGp5FNVVVpp0qpp}53MKK{BJW5?}k-as%rH{||<{iiiBFkpƄNbbb@@Bw9xL&[ύ7"""8@ s:r>>>'&&b6w툈gcc#pW\9_~#G<="EGGԞsS:... 6{IttrjOii)4kĮ!'8;;s܈7nந˞?"E}}=NYl /_bkkkr͝;wBAAAHHۺu:?dCCCwwsfffv ҫWbccmmmɩ=W6G 84&Ċh333rMAA <ֶ)66H$gΜ!_˺;wp8]zHGGGrjիWUn/^ %k\ӧB%%%I4O},,,._LGiii#GDDa&Mj~㣏>bx"h= Ça:IOO'=<<D_®~Q+wޥH9 X*dEEE۷o'ׅ@mܸ;mh: "44t޽zpD{g&u֭ 333SByjjjrrr֯_okkkaaNCoHKK;v,yC–'Nzw(lm\ws}U')Cf{ B.zW\INTH$:tPUUH$IR [=B(??f纫(9+WoZv [^^^TTdz􍎍0arŋm?ZU9fС4k@ 6n}k1W\AAH$244455DԶuVwwwrL&ۺuw_T#z.L.tO8JNNFZCZs!1]ӧObH$Fzz^kΝ;G@*>}>J理Bbcc{IoygXXXAAjkk8P\3pi9S[nzzzo-#8NO_PPPm5SL9)уxMZnmʕzzzz/n sNjjjbcc8Nhh(,qVVV|>?***//wEJs>..ɉ)d_*//D"Us l됧'B( %%wEj)..Dbӧ+b8:-C" 8w:r~X,ң\Zg+tHr<11!)ݽ{744HAl %C}cU233i5NNNqqq+oee%++++DN!kOMs[aC ȩ=eee | -B06T<~4.ϵƥ)4,td2ٚ5k\nhhh^^X,677'TCP($"44r|̘1\.Rƅ\t ]ISRR2|p##xcbb,--ɩ=ž<׀*4GGG@¿cԞANLQNݻ:q8ղ ;׀ _~?BBo=ڵkM*Oټys;|>ۻTAW1pX: B"̘1P5K95..{777wh &#055򲳳!k\? @n\} 2___ 'NPٳgɭlll >7odϭ#wSSSrb1 g\ۓ䧟~]`Ydgg BWW۷ow==QFڵA4IIIApܐ􂃃 Eff%Ks=t˗)tN8ajj:rH5o⴯ !t!:_jՐ!C?YYY={tssx͚5kĉ4yk֬?~9sOKKK$HBt47dffZYY5322 q\nnnyyyHҨ/~ڸqM122(-ڦ,X 44R;ѣGL} Ѵ̨3gNbbݻg͚ di鴃C {nח9::EzjرɧOf&q!M>̙3/^/**RrssCvBѣG.] dX.p8~~~W^U155]:Çd/^$'0oOx…ݻc%ڭ:a۷o>G  211?"###""6oތ؀w=z۱c,,,>:BH"p\Ϗ[xqEE"ziU:FC#Gӧϱcp5jkk Mk֬qqq?~~~mY.؀+W>rGlqIO~mBddyxxxUU \-Nzo ۫Wȉr=+WÇg,qPJ$BhҤI'O<{qjjjpZߺ"xj=nܸ߿yZv{wSSSܹ{=w9=trrrF흘Ȇ,R8p`JJJiiiHHׯq8NϞ=#G;))%oyyԿ3g?|=h O=֖=X|y;拉=﨣͉ ;B&88:ǔ͗WJgϞ}رc:Zpy-^\\Ķg,RHMMχܡϫqh ?0--ɓt_^)?ətݻw:tLJէWJ?vؕ+WfϞ OQB(x<(?OmTH$! :رc'NOqע |3iW\7oއ~((lZ! >;v̚5k<#{:/^ܰaƍY8mJiƌs΍zZ4l SSS1eʔHj v\^)ϮMMMk00#C>H$ Mk.HѸk0X:g\\ƍY>*ZlzEGG-[;v w-M*vXt9tϟ?m4xFނD"aT:uY.\˹wl QCocЉW矹\.ٲUXc?ӆ lmmi*Z bŊ]ׯ_ojj_9Nn|IZlϦv5jԨSN6 w9TTTobbsNrhУXExۼϞ=v˥& ZXXr \P(R)B(11q„ Xk󓒒޽˶%bYq999Hnp5_Sօ˫ǏlڴIS!dllCUhhرc,X@v@ |=S#H>ɉ(ЧO?7nmyyy7n+Vh\ccA::D"Yr%dԩzzz,XA7:mҥk֬] -_w:8t tޝ0q?dqCիW#bbbpF+Wl `w%mllo׺uqF_T~8NHHtH=Tw͙3G& K*j-/^_.);;pig޽{y<ޣG@8qB!am˖-qPWWףGxSNHtYnԩS{Ic1#z-XPb޼y={;;m200ЁȌj'222BE &L@Akaȯ_ZZ6'oE_|||?M2EP{**sε]7!̴QMMц hͼ^z^VVt¢w!׿L?[om>|\?˗3OM]]3x8coҥ}opBܵtك|}}.b֭]6o {͇3744, 3fl޼YC!}%=/^3\ ŋoݺz[$%%qܐt)%:#FuӢE>} 3_ -,,v؁ ̚\kFgϝ;_ms=3F;wY >.\XRR|X:.\иA\\\ƌv-CG.gff>K5V-:uTnn.BNk:>|,/Ǝk.܅2t_ׯ_?,Zqܹsڵ n'Zݻw=<\SSZNAA R3e2١Cpt#HpUDh"kkkKKŋ744t999~5W( &M 9~t-88Xwh#Gu}̙%%%+<{ !|( HMM%bȑ/_ܻwo'_)pe˖6wIɓ'¸su>!aÆfgg.x!dmm.pBRRҒ%K߯_K۷ڵk|y}}=Q8 秦8qYYYi߽Q~bo?YPPn:uyBS1]FޘxoGڿ?ΚP(Mի{S&W(4ZZ !G?(8=:Ul?!J~K~|J@@@gt$''ԔUwʕe˖9::R3rssoݺEa,'$###$$VOO{l[o.B!:Nyy9B[nd픔dddxyy}7l{C^ۛv}}}>~Sl'D$]p!33իW۶m;p@TTMOoNSSBc*^|200 %㲲R iiiiii|rЦMhUU Dr…ׯ744޽[f 4iSUYY) &M:wwUg}×/_O!j;Ŕ`[a#?LRV" Iq\/B޽{T6ʕ+-,,z"~[4iҭ[=z~SE'jӦMB}O={_QQ1`3grP`` ڣ١RB Z# SE QΆ#?O>T堠 KKK J~CzzΝ;i*RM~iiiׯO?~x5?!VZv}y{{T$Uۗ2z蠠 ܵGC'""!J~={j]z!4}tBǎ#>Bh̘14>iҤ'OP ٶmB?D566R"EN<9o w}ɓ'4K+ ~SL<7Ay :tڴi}{l=pW H{:Ak˖-FFF(GaU}ut&LPWWיLPBG0hĈlh @#Fq9pAP(`@+,  !4bĈlr!hBhذa/.h?Bݺultq* ~?>uԼyvE"B\/;;w!B"ܹ׭[wersbmm CAS]]}ĉUV-\pEEE+oo7oB'888,]\D.*w9w\P}!tx{{CO1k׮ms&rti̡O.eB&&&xlUп\@dR/!!ؘ'&&у|3ɵI1+,,l~~~ X?+nnn2X7^_ĉ97&+FLJJd /abbafagpLQ$tɒ@{۶mV9-|VVV X[ٳ?#|7|?;kggBUX___ 7l_-Z: By|>fff^=**ի ܲe ) WX8::>| +W?ݻ˗?EM2ŋxxt0 { ?׏9|pZZڀ` xwqM]Ož*ą nQjZV՟uઢb*ֽ D@PCe>O BHn%7~3p9۷dW :.zѐ!C<<<|pSN]N7 t? "['&BHKK'AHOH!Xv@>>wss=rH aڵׯ_"CSlmmLgqQ\pB ,,,%%@ tWQQ葩SZ[[Bb#QrJt ߄SԄ֕ëg"Ə8n8P\\ bs!p3k֬KSSSM&fIII}!oW_}%Zs,ͱ0f777,++CIT|m;FݸqIGGGfǏ/m#HAu&cٲe?2:!===GfeݺuFFFx "!ϟ5k0L1qD\JNgʔ)Ǐ2:>}Bb?bKTWW󞐑`0mBXTT$G,^^^b4i$\N 7A e111="&á, /{X!˥hIMM4h$''[ZZJKPGGx ]Y`A]]ŋ{ NB>m۷8ڵk{űBܝ?~̙ⷓ$VH!&t`ԩ! 6˗/>}3fMihh?~BөD\ŋ?SUUCEzt 7+ .LNN.--~ Э[(D_ߟdU$rssutt,--l'--B}?OEzt 7SӧO/bbbzNۛvd@.ݷoϟpMMM\.~YfyF䪸ȳvڟ~Iv.\,~;&:z~s`cccRRRhnwo.֬Ycjjf|lNCC7|ӷo˗׷}ã-OMMݺ"rU\ɄUnnoӦMC19{ؙ&ࢨB$'' [md.tԾ'O .D(.@:{]...s:@7oիم|…Za XǏ| .dd2ҦLBv!@7ܹs<BGܹsdN:B={͛7kjj}&ILS{ IDATL166& f͚f\3!t͛7 HH>}Ǝ+(++{1ٳg_~kX:"11QUUU{?͞=b]vM tEbbمBp8III'O& f͚u zA(NI򪯯hdddkkKv!@ΙXZZ BG!ܼysr<'NLNNW[[ V&Lw!t_jj*Ñ0aB(55'@ȿ7o9wd#ցБpl$t*%%HBIIIqqޡŋ#G]^x ,&Lm۶W^v|бBHKKΎ*Bիd" P _`` %HjzzzC9>>Ϗ8m׮]6mz6ٵ(..B/B(>>B䄫Ç;>tBh,K~3+**222ğ=z46VG:!Իwooo?Bpvee対BqppxQCCCLJ t+444???//BtI&ijj]P8l6;??C:>dȐ( MmmmJJ [RXXX=|C:ZdӧG%&&Xӧ]PPvvv=B_rم̙3d]AAA:՝3gNdNyy /^Lv!@q 2oi'44K}2ɓdmmmmyy9rv\\\ &맓\cTUUɮ(. C[xq\\ܧO.DtϞ=[d مf``QRR·B߼yTLN1bСC.(4 2p@uuugϞ]`م PZZʷBd"Gl dqYYBN=zĈx:e݋/իٵ !t `pi_YYwߑ]!ddd;: 鱱d\.t$g``P__v!N455Ν{ak֬!KOO!TSSv!N-[VTTt ֮]GEv!N~ɍ7VZEv! BBCCϞ=[UUEv!۰aȑ#a UB|@ﯦ&.\a PSSSۅ:9rDO'oٲӓBhGYY!v!N7BCC矴4 Rnnŋ7nHv!hT*Bn :YO'o޼|҉NCXhh{ ă\~z s,F]=___MM͘ իlZfcgvx t6o޼(Cv-;w.55u߾} Zv`E.ҥK_xqm Wss?8w\GGGksu+͘1ct+**~7 K!mm !tz…CۓǏ7o 366&u:C@GWWWJN'o޼YUU.Z)##G~:ׯ: Ё+хz*992.]joo|rr[:h{:wΜ9sRiWVVfhhwKYȨРo>}СC/_L&ԬZjɒ%0R׭[Phh(m455IO.-gggUUU;;ϟ?ST˦&b&_lmؖ{فCv…Ç'@yi.PX,VBBرc̚>QnF}m߾wiĈ `٭@իW&&&| !t뛑rY,ߣY|aN͛7} N "S\\laaBG(ÇWRR7Iy޽X8@Q00E?}dnnηB9tдi:KJJ6lO?YYYItCƆo!B2d5)%ɓ鈈J 6ܑ]dڵk%5|%vSh4Zpp0Yȓϟ+++9ѩ]vظcH4tbbbܹpf.ad#Omll:@@>}455ێFR%:>|Xf͊+ &M(8ѣGΔQTGG[|(((:th:=cnn~M:λɒFI.t.\e BOB^ :.1xTr{:QQQ׮];y򤺺$?|𡬬ֶC:#}}l6=={8qHڜ9st:N={6ٵȉѣGw]\x1"czzz&M¥ALAAA5|p92#f[dooob6rӧ-q{O>Ji;Kw||-&5JB.ۣe޼ys]9|}}.g؋'Iy#ĉmfdd0n.8::u55)TjTTANNN~~~kk+I|R 77[!DFF}!dllZlB())H%Ν;Ӛ:=vر۷oR(-xDX<<>BHjjqRSS6C4pNйyҤI&R+0._u tl}||F{㰧wB =@;o߾W^mcc#!t\R__?""BB_/^oܸ!Dz€=~~~SLV t^SSsNn!;wX=*--o-Z-mAlvPP޽{ ^mۖ%VB=Zvv͛7n8bb*//'l:(iӦ;wNI3-pNիwjii]O:u9+++7 W(ׯ^:""b֬YoB`0fϞ|r# Bk.j@QN6166J%wB3f+..NYYJ򯦦fʔ)YYYzzzĉkkk322$=l0 tgXԤ]B:ȱZOO߾}[JdUuu)SJKKoݺ5h r!//A o=z_]?JffСCH:)Dž Lzybrb׮]gϞ1cƹs.KpԴ`ݻw\r˗/9B7Jnni j̙>LHH `*AEѪ\n6449lȞ?>k֬ʛ7o]PPP&&&cƌt*ڿ+W=ZYY9''GVAE$CҀb\rƌYYY2qO{:4mΜ9#ooCEFFFEE]Q@ť7ydv!F|TVVv) EGt:?dWlC\]])q!??V???kAEEEnnn+W OOO "AƎ?vXhiiYvy dWOAECh4󟖖R5jԁ<9x`R P\L&sK,qqqqqqYdL&ae455mڴՕNgff88m9so rÇڪaaa/_Ė|2,,LUUU[[;<<Ǐի{immP,o߾ TWWpuuuMMͰoJS԰0Mz@E eee==*ϯSVV z9^0p:>jԨ\:@=}4((NFFF nmmmdd!N z\zuڑ r<BȳӧSTcczک466RӧOm, !+*:@>eddL8!4hРflnn8qbff+//_ͥKƌ1bĥKl6x>1c\tIoޫW/CCØ܋E:@N옘aÆ!/]p$9s%GGGаa6pbbbLLLo.25&&!4}tA vgkkNMMuppPRR 22dFFFQ(ӧ߹sJ )#B0a;}t\m Wcc;V^˗/crHzʪ'\*ھxӧOJJJ!!!dWį8$$DIII__?""ӧOdW$] t(// RSSkaJ:aݸԴɮHZ@͛0 J+VeeeDDq ՞={uիWDDćȮH|ݸ={FvEdRɓ'شX:yűc _O555KK dggPER}||Sލ/_Μ9SGGb BHlTDnޞ7k566`k}d~?۷/J믿D655EEEƕ#Nk=ջQUUe``6d###%W"eo++\itVbb"BhРA◄]S3fLrrm ڰa˱-,,$X@ t).X܌9Sx6^K.1Dk0_-ǏB+ndb'N>|3\OOO 3f[V)..F8d:Jrvƌ#F8qk?MF@rX'Nϟ? #++S:'ꮯOJJ;wmBxzzfee1 cc۟8q7ٱ5Fa-B(88XkWX)SSSTFF.Zm 4ɓ' idd$ķ}ƍMMM%'BD7==-:\.h޽$MKK۷/B(<<ߖڒ7 VTTF:tH+B3txܹ9r$~ud؞3|hjj5j֭[\'ܹs!S @IIIXXJ>}"""%-B!_iTWWGDDGEE%,,D[ .q8nׯ_GHhc)--m+L[+t222B666_eeeٸJKKqOѣG---?rlѣG &`߿UQQ y5^-766&%%ukZL&355[˗,2>>~ %..\ׯCBBTTTtuu#""޿c|z7222Κ*ݶsssB/^YTT$~.:;;uJAIDAT{xxN722NKK*LQQ6W޽oNFW_J\vPAA6@^ú&ݻww=sY~D*څϟBׯ_'0 SؽQ2dF 8'_7. |yPP1O`B֭[NNN!Ǐ X622NURaa!a 22G'{ ݂x]r7n\VV׷ƕ'N1X)ccH)::`kk?\ |BXg#G&%%֍!4qD3'33}a``%1a]LL –!&L`0$T"UV }777nPb2tnn iMMM۷on#O:pԩƥ(ܮ0aĺ.[VTTZjd;d PX`ɓ' (.0te˖M2ٳg% 2݄Nccٳg ('''??!C|JvQLݏ_xj<)++ q8u-[TUU\~ӧE%ll;;aÆ:uJ5YrϞ=q '( =GѶlLBBvc1${:iӦh4\ZZ333}||6l؀ zvsO<9zR&M;v,NȈ=ճб^tMjjj$TNϟ?5jTuuuRRRjj E"""8κu$Q B^ 2dH~~3gx N޽|...f!. GD]yϞ=JJJwf Z[[?|@vE@>xxӧO󵴴B@$lm۶-]t͚5d P(Ǐ7668Xlٲɓ'?{%'}ݻwѣG]WA0ovvv/^Ɂ)v߾}{BB. UTTܻw/..pc1 ^ -Zɓ'&&&x5 ۷8p@[[{pc1ߧͅˮ䪫۵k9ڵkWXAvQ o \\\ L@]v555}aaaz"(s ^|8v3g"a7_eeUV^OvQ333s]xqǎ7:r-[6ugϞm߾H'Loׯ_Dd'''???[[[ltKuʕ_9s222$ `0\]]'M}x H? N/}᯾/˓VÇ'MNR FRRѣ. H0th4ɓ']\\BG$i9V\\;r>$%%]= A)++߃ >> i*B֭Qmɟ>}MC9sFszc͛6m搨EE$DztDMa|رfZr]=%iW>aaa؁^uuʁȮU<|L0̙3dW$Azzz!~Ǐ]BЉ FX!O:,`xl0l3g͛0`@nnnNN-33֭[FFF?=Q>'))iFFF!*l2;;***ƍ۽{7Bĉd@gؤ$]vU1&O.c dcO[IIIuuumw#G]tА!C.I8qbڴimblv-XNRIݻwB| م= &`00LPSSSfffۅ=ںuߍ9o޼YlYUUB1%%{=f9''gΜ9CmzKKKVVT1-,,fϞիW,\1nCɝqcW/ϟ?>566v[0w$wUƷ~>rlDIdй#| bNطo߾}.I@.A P:BA P:BA P:BA P:B9r/a@[EBBBhh(YHU (R20@A9 t B@>82̟IENDB`tins-1.1.0/tests/0000755000004100000410000000000012321542746013666 5ustar www-datawww-datatins-1.1.0/tests/shuffle_test.rb0000644000004100000410000000122012321542746016701 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins if Tins::Shuffle === Array class ShuffleTest < Test::Unit::TestCase def setup @a = [ 1, 2, 3 ] srand 666 end def test_shuffle assert_equal(a = [2, 3, 1], a = @a.shuffle) assert_not_same @a, a assert_equal(b = [3, 1, 2], b = @a.shuffle) assert_not_same a, b assert_not_same @a, b end def test_shuffle_bang assert_equal([2, 3, 1], a = @a.shuffle!) assert_same @a, a assert_equal([1, 2, 3], b = @a.shuffle!) assert_same a, b assert_same @a, b end end end end tins-1.1.0/tests/extract_last_argument_options_test.rb0000644000004100000410000000162612321542746023431 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class ExtractLastArgumentOptionsTest < Test::Unit::TestCase require 'tins/xt/extract_last_argument_options' def test_empty_argument_array arguments = [] result = arguments.extract_last_argument_options assert_equal [ [], {} ], result assert_not_same arguments, result.first end def test_argument_array_without_options arguments = [ 1, 2, 3 ] result = arguments.extract_last_argument_options assert_equal [ [ 1, 2, 3 ], {} ], result assert_not_same arguments, result.first end def test_argument_array_witt_options arguments = [ 1, 2, 3, { :foo => :bar } ] result = arguments.extract_last_argument_options assert_equal [ [ 1, 2, 3 ], { :foo => :bar } ], result assert_not_same arguments, result.first assert_not_same arguments.last, result.last end end end tins-1.1.0/tests/minimize_test.rb0000644000004100000410000000345512321542746017102 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class MinimizeTest < Test::Unit::TestCase class ::Array include Tins::Minimize end def test_minimize assert_equal [], [].minimize assert_equal [ 1..1 ], [ 1 ].minimize assert_equal [ 1..2 ], [ 1, 2 ].minimize assert_equal [ 1..1, 7..7 ], [ 1, 7 ].minimize assert_equal [ 1..3, 7..7, 11..14 ], [ 1, 2, 3, 7, 11, 12, 13, 14 ].minimize assert_equal [ 'A'..'C', 'G'..'G', 'K'..'M' ], [ 'A', 'B', 'C', 'G', 'K', 'L', 'M' ].minimize end def test_minimize! assert_equal [], [].minimize! assert_equal [ 1..1 ], [ 1 ].minimize! assert_equal [ 1..2 ], [ 1, 2 ].minimize! assert_equal [ 1..1, 7..7 ], [ 1, 7 ].minimize! assert_equal [ 1..3, 7..7, 11..14 ], [ 1, 2, 3, 7, 11, 12, 13, 14 ].minimize! assert_equal [ 'A'..'C', 'G'..'G', 'K'..'M' ], [ 'A', 'B', 'C', 'G', 'K', 'L', 'M' ].minimize! end def test_unminimize assert_equal [], [].unminimize assert_equal [ 1 ], [ 1..1 ].unminimize assert_equal [ 1, 2 ], [ 1..2 ].unminimize assert_equal [ 1, 7 ], [ 1..1, 7..7 ].unminimize assert_equal [ 1, 2, 3, 7, 11, 12, 13, 14 ], [ 1..3, 7..7, 11..14 ].unminimize assert_equal [ 'A', 'B', 'C', 'G', 'K', 'L', 'M' ], [ 'A'..'C', 'G'..'G', 'K'..'M' ].unminimize end def test_unminimize! assert_equal [], [].unminimize! assert_equal [ 1 ], [ 1..1 ].unminimize! assert_equal [ 1, 2 ], [ 1..2 ].unminimize! assert_equal [ 1, 7 ], [ 1..1, 7..7 ].unminimize! assert_equal [ 1, 2, 3, 7, 11, 12, 13, 14 ], [ 1..3, 7..7, 11..14 ].unminimize! assert_equal [ 'A', 'B', 'C', 'G', 'K', 'L', 'M' ], [ 'A'..'C', 'G'..'G', 'K'..'M' ].unminimize! end end end tins-1.1.0/tests/deep_const_get_test.rb0000644000004100000410000000202012321542746020226 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt/deep_const_get' module Tins class DeepConstGetTest < Test::Unit::TestCase module A module B end end module C module NotB end def self.const_missing(c) NotB end end def test_deep_const_get_with_start_module assert_raise(ArgumentError) { deep_const_get '::B', A } assert_equal A::B, deep_const_get('B', A) end def test_deep_const_get_without_start_module assert_equal Tins::DeepConstGetTest::A::B, deep_const_get('::Tins::DeepConstGetTest::A::B') assert_equal Tins::DeepConstGetTest::A::B, deep_const_get('Tins::DeepConstGetTest::A::B') assert_equal Array, deep_const_get('::Array') assert_equal Array, deep_const_get('Array') end def test_deep_const_get_with_const_missing assert_raise(ArgumentError) { deep_const_get '::Tins::DeepConstGetTest::A::D' } assert_equal Tins::DeepConstGetTest::C::NotB, deep_const_get('::Tins::DeepConstGetTest::C::B') end end end tins-1.1.0/tests/time_freezer_test.rb0000644000004100000410000000067412321542746017741 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class TimeFreezerTest < Test::Unit::TestCase def test_freezing freezing_point = '2011-11-11T11:11:11' Tins::TimeFreezer.freeze(freezing_point) do assert_equal freezing_point, Time.now.strftime('%FT%T') assert_equal freezing_point, DateTime.now.strftime('%FT%T') assert_equal freezing_point[0, 10], Date.today.strftime('%F') end end end end tins-1.1.0/tests/bijection_test.rb0000644000004100000410000000071112321542746017217 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class BijectionTest < Test::Unit::TestCase def test_bijection assert_equal [ [ 1, 2 ], [ 3, 4 ] ], Tins::Bijection[ 1, 2, 3, 4 ].to_a.sort assert_raise(ArgumentError) do Tins::Bijection[1,2,3] end assert_raise(ArgumentError) do Tins::Bijection[1,2,3,2] end assert_raise(ArgumentError) do Tins::Bijection[1,2,1,3] end end end end tins-1.1.0/tests/annotate_test.rb0000644000004100000410000000131512321542746017063 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class AnnotateTest < Test::Unit::TestCase require 'tins/xt/annotate' class A annotate :foo annotate :bar foo 'test foo1' bar 'test bar1' def first end foo 'test foo2' bar 'test bar2' def second end bar 'test bar3' def third end end def test_annotations assert_equal 'test foo1', A.foo_of(:first) assert_equal 'test bar1', A.bar_of(:first) assert_equal 'test foo2', A.foo_of(:second) assert_equal 'test bar2', A.bar_of(:second) assert_equal nil, A.foo_of(:third) assert_equal 'test bar3', A.bar_of(:third) end end end tins-1.1.0/tests/deep_dup_test.rb0000644000004100000410000000061012321542746017034 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class DeepDupTest < Test::Unit::TestCase def test_deep_dup a = [1,2,3] assert_equal a, a.deep_dup assert_not_same a, a.deep_dup end def test_deep_dup_proc f = lambda { |x| 2 * x } g = f.deep_dup assert_equal f[3], g[3] assert_equal f, g assert_same f, g end end end tins-1.1.0/tests/from_module_test.rb0000644000004100000410000000170612321542746017566 0ustar www-datawww-datarequire 'test_helper' require 'tins' class FromModuleTest < Test::Unit::TestCase module MyIncludedModule def foo :foo end def bar :bar end end class MyKlass def foo :original_foo end def bar :original_bar end end class DerivedKlass < MyKlass extend Tins::FromModule include from :module => MyIncludedModule, :methods => [ :foo ] end module MyModule def foo :original_foo end def bar :original_bar end include MyIncludedModule end class AnotherDerivedKlass include MyModule extend Tins::FromModule include from :module => MyIncludedModule, :methods => :foo end def test_derived_klass c = DerivedKlass.new assert_equal :foo, c.foo assert_equal :original_bar, c.bar end def test_another_derived_klass c = AnotherDerivedKlass.new assert_equal :foo, c.foo assert_equal :original_bar, c.bar end end tins-1.1.0/tests/attempt_test.rb0000644000004100000410000000617312321542746016737 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class AttemptTest < Test::Unit::TestCase def test_attempt_block_condition assert attempt(:attempts => 1, :exception_class => nil) { |c| c == 1 } assert attempt(:attempts => 3, :exception_class => nil) { |c| c == 1 } assert_equal false, attempt(:attempts => 3, :exception_class => nil) { |c| c == 4 } assert_nil attempt(:attempts => 0, :exception_class => nil) { |c| c == 4 } assert_raise(Exception) { attempt(:attempts => 3, :exception_class => nil) { raise Exception } } end class MyError < StandardError; end class MyException < Exception; end def test_attempt_default_exception assert attempt(1) { |c| c != 1 and raise MyError } assert attempt(3) { |c| c != 1 and raise MyError } assert_equal false, attempt(3) { |c| c != 4 and raise MyError } assert_nil attempt(0) { |c| c != 4 and raise MyError } assert_raise(Exception) { attempt(3) { raise Exception } } end def test_attempt_exception assert attempt(:attempts => 1, :exception_class => MyException) { |c| c != 1 and raise MyException } assert attempt(:attempts => 3, :exception_class => MyException) { |c| c != 1 and raise MyException } assert_nil attempt(:attempts => 0, :exception_class => MyException) { |c| c != 4 and raise MyException } assert_raise(Exception) { attempt(:attempts => 3, :exception_class => MyException) { raise Exception } } end def test_reraise_exception tries = 0 assert_raise(MyException) do attempt(:attempts => 3, :exception_class => MyException, :reraise => true) do |c| tries = c; raise MyException end end assert_equal 3, tries end def test_reraise_exception_with_numeric_sleep tries = 0 singleton_class.class_eval do define_method(:sleep_duration) do |duration, count| assert_equal 10, duration tries = count super 0, count # Let's not really sleep that long… end end assert_raise(MyException) do attempt(:attempts => 3, :exception_class => MyException, :reraise => true, :sleep => 10) do |c| raise MyException end end assert_equal 2, tries ensure singleton_class.class_eval do method_defined?(:sleep_duration) and remove_method :sleep_duration end end def test_reraise_exception_with_proc_sleep tries = 0 singleton_class.class_eval do define_method(:sleep_duration) do |duration, count| assert_kind_of Proc, duration tries = count super duration, count end end assert_raise(MyException) do attempt(:attempts => 3, :exception_class => MyException, :reraise => true, :sleep => lambda { |x| 0 }) do |c| raise MyException end end assert_equal 2, tries ensure singleton_class.class_eval do method_defined?(:sleep_duration) and remove_method :sleep_duration end end private def singleton_class class << self; self; end end unless method_defined?(:singleton_class) end end tins-1.1.0/tests/hash_symbolize_keys_recursive_test.rb0000644000004100000410000000077412321542746023424 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class HashSymbolizeKeysRecursiveTest < Test::Unit::TestCase require 'tins/xt/hash_symbolize_keys_recursive' def test_symbolize hash = { 'key' => [ { 'key' => { 'key' => true } } ], } hash2 = hash.symbolize_keys_recursive assert hash2[:key][0][:key][:key] hash.symbolize_keys_recursive! assert hash[:key][0][:key][:key] end end end tins-1.1.0/tests/p_test.rb0000644000004100000410000000037512321542746015516 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt/p' module Tins class PTest < Test::Unit::TestCase def test_p_bang assert_raise(RuntimeError) { p! "foo" } end def test_pp_bang assert_raise(RuntimeError) { pp! "foo" } end end end tins-1.1.0/tests/limited_test.rb0000644000004100000410000000071512321542746016704 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class LimitedTest < Test::Unit::TestCase class ::Array include Tins::Shuffle end def test_limited count = {} limited = Tins::Limited.new(5) 5.times do limited.execute do count[Thread.current] = true sleep end end until count.size >= 5 sleep 0.1 end assert_equal 5, count.keys.uniq.size end end end tins-1.1.0/tests/partial_application_test.rb0000644000004100000410000000131412321542746021270 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class PartialApplicationTest < Test::Unit::TestCase def mul(x, y) x * y end define_method(:dup) { |y| method(:mul).partial(2)[y] } define_method(:trip) { |y| method(:mul).partial(3)[y] } def test_proc mul = lambda { |x, y| x * y } klon = mul.partial dup = mul.partial(2) trip = mul.partial(3) assert_equal [ 6, 9, 12 ], [ dup[3], trip[3], mul[4, 3] ] assert_equal [ 6, 9, 12 ], [ dup[3], trip[3], klon[4, 3] ] assert_raises(ArgumentError) do mul.partial(1, 2, 3) end end def test_method assert_equal [ 6, 9, 12 ], [ dup(3), trip(3), mul(4, 3) ] end end end tins-1.1.0/tests/rotate_test.rb0000644000004100000410000000240612321542746016552 0ustar www-datawww-datarequire 'test_helper' module Tins class RotateTest < Test::Unit::TestCase def test_rotate_bang a = [ 1, 2, 3 ] assert_same a, a.rotate! end def test_rotate_bang_0 a = [ 1, 2, 3 ] assert_equal [ 1, 2, 3 ], a.rotate!(0) end def test_rotate_bang_1 a = [ 1, 2, 3 ] assert_equal [ 2, 3, 1 ], a.rotate!(1) end def test_rotate_bang_2 a = [ 1, 2, 3 ] assert_equal [ 3, 1, 2 ], a.rotate!(2) end def test_rotate_bang_minus_1 a = [ 1, 2, 3 ] assert_equal [ 3, 1, 2 ], a.rotate!(-1) end def test_rotate_bang_minus_2 a = [ 1, 2, 3 ] assert_equal [ 2, 3, 1 ], a.rotate!(-2) end def test_rotate a = [ 1, 2, 3 ] assert_not_same a, a.rotate end def test_rotate_0 a = [ 1, 2, 3 ] assert_equal [ 1, 2, 3 ], a.rotate(0) end def test_rotate_1 a = [ 1, 2, 3 ] assert_equal [ 2, 3, 1 ], a.rotate(1) end def test_rotate_2 a = [ 1, 2, 3 ] assert_equal [ 3, 1, 2 ], a.rotate(2) end def test_rotate_minus_1 a = [ 1, 2, 3 ] assert_equal [ 3, 1, 2 ], a.rotate(-1) end def test_rotate_minus_2 a = [ 1, 2, 3 ] assert_equal [ 2, 3, 1 ], a.rotate(-2) end end end tins-1.1.0/tests/responding_test.rb0000644000004100000410000000116212321542746017422 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class RespondingTest < Test::Unit::TestCase class A def foo() end def bar() end end def test_responding assert_equal true, responding?(:foo) === A.new assert_equal false, responding?(:jflafjdklfjaslkdfj) === A.new assert_equal false, responding?(:jflafjdklfjaslkdfj, :foo) === A.new assert_equal true, responding?(:foo, :bar) === A.new end def test_responding_to_s assert_equal 'Responding to foo', responding?(:foo).to_s assert_equal 'Responding to foo', responding?(:foo).inspect end end end tins-1.1.0/tests/subhash_test.rb0000644000004100000410000000212712321542746016711 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class SubhashTest < Test::Unit::TestCase require 'tins/xt/subhash' def test_subhash h = { 'foo1' => 1, 'foo2' => 2, 'bar666' => 666 } assert_equal [ [ 'bar666', 666 ] ], h.subhash(/\Abar/).to_a assert h.subhash(/\Abaz/).empty? assert_equal [ [ 'foo1', 1 ], [ 'foo2', 2 ] ], h.subhash(/\Afoo\d/).sort assert_equal [ [ 'foo2', 2 ] ], h.subhash('foo2').to_a end def test_subhash_bang h = { 'foo1' => 1, 'foo2' => 2, 'bar666' => 666 } h.subhash!('foo2') assert_equal [ [ 'foo2', 2 ] ], h.to_a end def test_subhash_with_block h = { 'foo1' => 1, 'foo2' => 2, 'bar666' => 666 } assert h.subhash(/\Abaz/) { :foo }.empty? assert_equal [ [ 'foo1', 1 ], [ 'foo2', 2 ] ], h.subhash(/\Afoo(\d)/) { |_,_,m| Integer(m[1]) }.to_a.sort end def test_subhash_with_default_proc h = Hash.new { |h, k| h[k] = :foo } h.update('foo' => 1, 'bar' => 2) s = h.subhash('foo') assert_equal 1, s['foo'] assert_equal :foo, s['bar'] end end end tins-1.1.0/tests/uniq_by_test.rb0000644000004100000410000000142712321542746016724 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class UniqByTest < Test::Unit::TestCase unless defined?(Point) class Point < Struct.new :x, :y end end def test_uniq_by assert_equal [ 1, 2, 3 ], [ 1, 2, 2, 3 ].uniq_by.sort a = [ 1, 2, 2, 3 ]; a.uniq_by! assert_equal [ 1, 2, 3 ], a.sort p1 = Point.new 1, 2 p2 = Point.new 2, 2 p3 = Point.new 2, 2 p4 = Point.new 3, 3 a = [ p1, p2, p3, p4 ] a_uniq = a.uniq_by { |p| p.y } assert_equal 2, a_uniq.size assert a_uniq.include?(p4) assert [ p1, p2, p3 ].any? { |p| a_uniq.include? p } a.uniq_by! { |p| p.y } assert_equal 2, a.size assert a.include?(p4) assert [ p1, p2, p3 ].any? { |p| a.include? p } end end end tins-1.1.0/tests/token_test.rb0000644000004100000410000000216712321542746016400 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class TokenTest < Test::Unit::TestCase def test_token_failures assert_raises(ArgumentError) { Tins::Token.new(:bits => 0) } assert_raises(ArgumentError) { Tins::Token.new(:length => 0) } assert_raises(ArgumentError) { Tins::Token.new(:alphabet => %w[0]) } end def test_token_for_length token = Tins::Token.new(:length => 22) assert_equal 22, token.length assert_equal 130, token.bits end def test_token_for_bits token = Tins::Token.new(:bits => 128) assert_equal 22, token.length # can differ from bits argument depending on alphabet: assert_equal 130, token.bits end def test_alphabet token = Tins::Token.new(:alphabet => %w[0 1]) assert_equal 128, token.length assert_equal 128, token.bits token = Tins::Token.new(:alphabet => %w[0 1 2 3]) assert_equal 64, token.length assert_equal 128, token.bits token = Tins::Token.new(:length => 128, :alphabet => %w[0 1 2 3]) assert_equal 128, token.length assert_equal 256, token.bits end end end tins-1.1.0/tests/file_binary_test.rb0000644000004100000410000000352112321542746017536 0ustar www-datawww-datarequire 'test_helper' require 'tempfile' require 'tins/xt' module Tins class TinsFileBinaryTest < Test::Unit::TestCase def test_ascii_buffer_size write_file do |file| file.write "A" * 10 + "\x00" assert_equal true, file.ascii?(:buffer_size => 10) assert_equal true, File.ascii?(file.path, :buffer_size => 10) assert_equal false, file.binary?(:buffer_size => 10) assert_equal false, File.binary?(file.path, :buffer_size => 10) end end def test_binary write_file do |file| file.write "A" * 69 + "\x01" * 31 assert_equal true, file.binary? assert_equal true, File.binary?(file.path) assert_equal false, file.ascii? assert_equal false, File.ascii?(file.path) end end def test_ascii_offset write_file do |file| file.write "\x01" * 31 + "A" * 70 assert_equal false, file.binary?(:offset => 1) assert_equal false, File.binary?(file.path, :offset => 1) assert_equal true, file.ascii?(:offset => 1) assert_equal true, File.ascii?(file.path, :offset => 1) end end def test_binary_zero write_file do |file| file.write "A" * 50 + "\0" + "A" * 49 assert_equal true, file.binary? assert_equal true, File.binary?(file.path) assert_equal false, file.ascii? assert_equal false, File.ascii?(file.path) end end def test_ascii write_file do |file| file.write "A" * 100 assert_equal false, file.binary? assert_equal false, File.binary?(file.path) assert_equal true, file.ascii? assert_equal true, File.ascii?(file.path) end end private def write_file File.open(File.join(Dir.tmpdir, "temp.#$$"), 'wb+') do |file| yield file end end end end tins-1.1.0/tests/null_test.rb0000644000004100000410000000371312321542746016230 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class NullTest < Test::Unit::TestCase require 'tins/xt/null' def test_null assert_equal NULL, NULL.foo assert_equal NULL, NULL.foo.bar assert_equal 'NULL', NULL.inspect assert_equal '', NULL.to_s assert_equal 0, NULL.to_i assert_equal 0.0, NULL.to_f assert_equal [], NULL.to_a assert_equal 1, null(1) assert_equal 1, Null(1) assert_equal NULL, null(nil) assert_equal NULL, Null(nil) assert_equal NULL, NULL::NULL assert NULL.nil? assert NULL.blank? assert_equal nil, NULL.as_json assert_equal 'null', NULL.to_json end def test_null_plus assert_equal 1, null_plus(:value => 1) assert_equal 1, NullPlus(:value => 1) assert_kind_of Tins::NullPlus, null_plus(:value => nil) assert_kind_of Tins::NullPlus, NullPlus(:value => nil) assert_kind_of Tins::NullPlus, null_plus assert_kind_of Tins::NullPlus, NullPlus() assert_kind_of Tins::NullPlus, null_plus.foo assert_kind_of Tins::NullPlus, null_plus.foo.bar assert_kind_of Tins::NullPlus, NullPlus().foo assert_kind_of Tins::NullPlus, NullPlus().foo.bar assert null_plus.nil? assert null_plus().blank? assert_equal nil, null_plus().as_json assert_equal 'null', null_plus.to_json assert NullPlus().nil? assert NullPlus().blank? assert_equal nil, NullPlus().as_json assert_equal 'null', NullPlus().to_json end def foo 1 / 0 rescue => e null_plus(:error => e) end def test_null_plus_caller_and_misc assert_match /foo/, foo.caller.first if foo.respond_to?(:caller_locations) assert_kind_of Thread::Backtrace::Location, foo.caller_locations.first assert_match /foo/, foo.caller_locations.first.to_s end assert_match /foo/, foo.caller.first assert_kind_of ZeroDivisionError, foo.error end end end tins-1.1.0/tests/lines_file_test.rb0000644000004100000410000000513312321542746017365 0ustar www-datawww-datarequire 'test_helper' require 'tempfile' require 'tins/lines_file' module Tins class TinsLinesFileTest < Test::Unit::TestCase FILE = < 23 }.blank? assert "".blank? assert " ".blank? assert !"foo".blank? end def test_present assert true.present? assert !false.present? assert !nil.present? assert ![].present? assert [23].present? assert !Set[].present? assert Set[23].present? assert !{}.present? assert({ :foo => 23 }.present?) assert !"".present? assert !" ".present? assert "foo".present? end def test_full assert_equal true, true.full? assert_nil false.full? assert_nil nil.full? assert_nil [].full? assert_equal [ 23 ], [ 23 ].full? assert_nil Set[].full? assert_equal Set[23], Set[23].full? assert_nil({}.full?) assert_equal({ :foo => 23 }, { :foo => 23 }.full?) assert_nil "".full? assert_nil " ".full? assert_equal "foo", "foo".full? assert_nil " ".full?(&:size) assert_equal 3, "foo".full?(&:size) assert_nil " ".full?(&:size) assert_equal 3, "foo".full?(&:size) assert_nil " ".full?(:size) assert_equal 3, "foo".full?(:size) assert_nil " ".full?(:size) assert_equal 3, "foo".full?(:size) end def test_all_full assert_equal [1, 2], [1, 2].all_full? assert_nil [nil, 2].all_full? assert_nil [1, ''].all_full? end def test_all_full_with_block [1, 2].all_full? do |x, y| assert_equal 1, x assert_equal 2, y end ['', 2].all_full? do |x, y| assert false end end end end tins-1.1.0/tests/range_plus_test.rb0000644000004100000410000000050112321542746017405 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class RangePlustTest < Test::Unit::TestCase def test_range_plus assert_equal [], (0...0) + (0...0) assert_equal [ 0 ], (0..0) + (0...0) assert_equal [ 0, 0 ], (0..0) + (0..0) assert_equal((1..5).to_a, (1...3) + (3..5)) end end end tins-1.1.0/tests/sexy_singleton_test.rb0000644000004100000410000000037312321542746020327 0ustar www-datawww-datarequire 'tins' class SexySingletonTest < Test::Unit::TestCase class Single include Tins::SexySingleton def foo :foo end end def test_foo assert_equal :foo, Single.instance.foo assert_equal :foo, Single.foo end end tins-1.1.0/tests/memoize_test.rb0000644000004100000410000000312212321542746016715 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class MemoizeTest < Test::Unit::TestCase class FooBar def foo(*a) @@foo ||= 0 @@foo += 1 end memoize_method :foo def bar(*a) @@bar ||= 0 @@bar += 1 end memoize_function :bar end def test_method_cache fb1 = FooBar.new fb2 = FooBar.new assert_equal true, fb1.__memoize_cache__.empty? assert_equal true, fb2.__memoize_cache__.empty? assert_equal 1, fb1.foo(1, 2) assert_equal 2, fb2.foo(1, 2) assert_equal 3, fb1.foo(1, 2, 3) assert_equal 4, fb2.foo(1, 2, 3) assert_equal 1, fb1.foo(1, 2) assert_equal 2, fb2.foo(1, 2) fb1.memoize_cache_clear fb2.memoize_cache_clear assert_equal true, fb1.__memoize_cache__.empty? assert_equal true, fb2.__memoize_cache__.empty? assert_equal 5, fb1.foo(1, 2) assert_equal 6, fb2.foo(1, 2) assert_equal 5, fb1.foo(1, 2) assert_equal 6, fb2.foo(1, 2) assert_equal false, fb1.__memoize_cache__.empty? assert_equal false, fb2.__memoize_cache__.empty? end def test_function_cache fb1 = FooBar.new fb2 = FooBar.new assert_equal 1, fb1.bar(1, 2) assert_equal 1, fb2.bar(1, 2) assert_equal 2, fb1.bar(1, 2, 3) assert_equal 2, fb2.bar(1, 2, 3) assert_equal 1, fb1.bar(1, 2) assert_equal 1, fb2.bar(1, 2) FooBar.memoize_cache_clear assert_equal 3, fb1.bar(1, 2) assert_equal 3, fb2.bar(1, 2) assert_equal false, FooBar.__memoize_cache__.empty? end end end tins-1.1.0/tests/module_group_test.rb0000644000004100000410000000107312321542746017754 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class ModuleGroupTest < Test::Unit::TestCase MyClasses = Tins::ModuleGroup[ Array, String, Hash ] def test_module_group assert MyClasses === [] assert MyClasses === "" assert MyClasses === {} assert !(MyClasses === :nix) case [] when MyClasses assert true when Array assert false end case :nix when MyClasses assert false when Array assert false when Symbol assert true end end end end tins-1.1.0/tests/require_maybe_test.rb0000644000004100000410000000105412321542746020103 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins require 'tins/xt/require_maybe' class RequireMaybeTest < Test::Unit::TestCase def test_require_maybe_failed executed = false require_maybe 'nix' do executed = true end assert executed, 'require did not fail' end def test_require_maybe_succeeded not_executed = true result = require_maybe 'tins' do not_executed = false end assert [ false, true ].include?(result) assert not_executed, 'require failed' end end end tins-1.1.0/tests/string_byte_order_mark_test.rb0000644000004100000410000000226712321542746022017 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins if defined? ::Encoding class StringByteOrderMarkTest < Test::Unit::TestCase def test_no_bom_encoding assert_nil "abcdef".bom_encoding end def test_utf8_bom_encoding assert_equal Encoding::UTF_8, "\xef\xbb\xbf".bom_encoding end def test_utf16be_bom_encoding assert_equal Encoding::UTF_16BE, "\xfe\xff".bom_encoding end def test_utf16le_bom_encoding assert_equal Encoding::UTF_16LE, "\xff\xfe".bom_encoding end def test_utf32be_bom_encoding assert_equal Encoding::UTF_32BE, "\x00\x00\xff\xfe".bom_encoding end def test_utf32le_bom_encoding assert_equal Encoding::UTF_32LE, "\xff\xfe\x00\x00".bom_encoding end def test_utf7_bom_encoding assert_equal Encoding::UTF_7, "\x2b\x2f\x76\x38".bom_encoding assert_equal Encoding::UTF_7, "\x2b\x2f\x76\x39".bom_encoding assert_equal Encoding::UTF_7, "\x2b\x2f\x76\x2b".bom_encoding assert_equal Encoding::UTF_7, "\x2b\x2f\x76\x2f".bom_encoding assert_equal Encoding::UTF_7, "\x2b\x2f\x76\x38\x2d".bom_encoding end end end end tins-1.1.0/tests/hash_union_test.rb0000644000004100000410000000173512321542746017413 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class HashUnionTest < Test::Unit::TestCase class HashLike1 def to_hash { 'foo' => true } end end class HashLike2 def to_h { 'foo' => true } end end def test_union defaults = { 'foo' => true, 'bar' => false, 'quux' => nil } hash = { 'foo' => false } assert_equal [ ['bar', false], ['foo', false], ['quux', nil] ], (hash | defaults).sort hash |= defaults assert_equal [ ['bar', false], ['foo', false], ['quux', nil] ], hash.sort hash = { 'foo' => false } hash |= { 'quux' => true, 'baz' => 23, } | defaults assert_equal [ ['bar', false], [ 'baz', 23 ], ['foo', false], ['quux', true] ], hash.sort end def test_hash_conversion assert_equal({ 'foo' => true }, { } | HashLike1.new) assert_equal({ 'foo' => true }, { } | HashLike2.new) end end end tins-1.1.0/tests/dslkit_test.rb0000644000004100000410000001366712321542746016561 0ustar www-datawww-datarequire 'test_helper' require 'tins' class TL def initialize make_baz end extend Tins::ThreadLocal thread_local :foo include Tins::ThreadLocal def make_baz instance_thread_local :baz end extend Tins::ThreadGlobal thread_global :bar end class IE include Tins::InstanceExec def initialize(&block) @block = block end def exec instance_exec(&@block) end def foo :foo end end class C extend Tins::Constant constant :foo constant :bar, :baz end class DA extend Tins::DSLAccessor dsl_accessor :foo dsl_accessor :bar, :bar dsl_accessor :baz do :baz end dsl_accessor :quux, :qu, :ux dsl_reader :on, true dsl_reader :off, false dsl_reader :states do [ on, off ] end dsl_reader :abc, *%w[a b c] end class I include Tins::Interpreter def foo :foo end def y 2 end end class S include Tins::InstanceExec include Tins::SymbolMaker end module K extend Tins::ConstantMaker end module D extend Tins::Deflect end class D2 extend Tins::Delegate def initialize @ary = [ 1, 2, 3 ] end attr_reader :ary delegate :my_size1, :@ary, :size delegate :my_size2, :ary, :size delegate :size, :ary delegate :length, :ary end class D3 < Tins::MethodMissingDelegator::DelegatorClass end require 'test/unit' require 'tempfile' class PoliteTest < Test::Unit::TestCase def setup @tl = TL.new @tl2 = TL.new @ie = IE.new { foo } @c = C.new @da = DA.new @i = I.new end def test_version assert_equal Tins::VERSION_ARRAY * '.', Tins::VERSION end def test_thread_local assert_nil @tl.foo @tl.foo = 1 assert_equal 1, @tl.foo new_foo = nil thread = Thread.new do @tl.foo = 2 new_foo = @tl.foo end thread.join assert_equal 2, new_foo assert_equal 1, @tl.foo assert_equal @tl.baz, @tl2.baz end def test_instance_thread_local assert_nil @tl.baz @tl.baz = 1 assert_equal 1, @tl.baz new_foo = nil thread = Thread.new do @tl.baz = 2 new_foo = @tl.baz end thread.join assert_equal 2, new_foo assert_equal 1, @tl.baz assert_not_equal @tl.baz, @tl2.baz end def test_thread_global assert_nil @tl.bar @tl.bar = 1 assert_equal 1, @tl.bar new_bar = nil thread = Thread.new do @tl.bar = 2 new_bar = @tl.bar end thread.join assert_equal 2, new_bar assert_equal 2, @tl.bar end def test_instance_exec assert_equal :foo, @ie.foo assert_equal :foo, @ie.exec @ie.freeze assert_equal :foo, @ie.foo assert_equal :foo, @ie.exec end def test_constant assert_equal :foo, @c.foo assert_equal :baz, @c.bar end def test_dsl_accessor assert_nil @da.foo assert_equal :bar, @da.bar assert_equal :baz, @da.baz assert_equal [:qu, :ux], @da.quux @da.foo 1 @da.bar 2 @da.baz 3 assert_equal 1, @da.foo assert_equal 2, @da.bar assert_equal 3, @da.baz end def test_dsl_reader assert_equal true, @da.on assert_equal false, @da.off assert_raises(ArgumentError) do @da.on false end assert_equal [ @da.on, @da.off ], @da.states assert_equal %w[a b c], @da.abc @da.abc << 'd' assert_equal %w[a b c d], @da.abc @da.instance_variable_set :@abc, %w[a b c] assert_equal %w[a b c], @da.abc end def test_dsl_accessor_multiple assert_nil @da.foo assert_equal :bar, @da.bar @da.foo 1, 2 @da.bar [1, 2] assert_equal [1, 2], @da.foo assert_equal [1, 2], @da.bar @da.bar [1, 2, *@da.bar] assert_equal [1, 2] * 2, @da.bar end def test_interpreter assert_equal :foo, @i.interpret('foo') temp = Tempfile.new('foo') temp.write 'foo' temp.rewind assert_equal :foo, @i.interpret(temp) end def test_interpreter_with_args assert_equal 3, @i.interpret('|x| x + y', 1) temp = Tempfile.new('foo') temp.write '|x| x + y' temp.rewind assert_equal 3, @i.interpret(temp, 1) end def test_symbol_maker s = S.new assert_equal(:foo, s.instance_exec { foo }) assert_raises(NoMethodError) { s.instance_exec { foo 1 }} end def test_constant_maker assert_equal(:FOO, K::FOO) end def test_deflect_block assert_raises(NoMethodError) { 1.foo } assert !D.deflect?(Integer, :foo) D.deflect(Integer, :foo, Tins::Deflect::Deflector.new { :foo }) do assert_equal :foo, 1.foo assert D.deflect?(Integer, :foo) end assert !D.deflect?(Integer, :foo) assert_raises(NoMethodError) { 1.foo } end def test_deflect assert_raises(NoMethodError) { 1.foo } assert !D.deflect?(Integer, :foo) D.deflect_start(Integer, :foo, Tins::Deflect::Deflector.new { :foo }) assert_equal :foo, 1.foo assert D.deflect?(Integer, :foo) t = Thread.new do assert !D.deflect?(Integer, :foo) assert_raises(NoMethodError) { 1.foo } end t.join D.deflect_stop(Integer, :foo) assert !D.deflect?(Integer, :foo) assert_raises(NoMethodError) { 1.foo } end def test_deflect_method_missing assert_raises(NoMethodError) { 1.foo } assert !D.deflect?(Integer, :method_missing) D.deflect_start(Integer, :method_missing, Tins::Deflect::Deflector.new { :foo }) assert_equal :foo, 1.foo assert D.deflect?(Integer, :method_missing) t = Thread.new do assert !D.deflect?(Integer, :method_missing) assert_raises(NoMethodError) { 1.foo } end t.join D.deflect_stop(Integer, :method_missing) assert !D.deflect?(Integer, :method_missing) assert_raises(NoMethodError) { 1.foo } end def test_delegate d = D2.new assert_equal 3, d.my_size1 assert_equal 3, d.my_size2 assert_equal 3, d.size assert_equal 3, d.length end def test_delegate_d3 d = D3.new [] assert_equal 0, d.size d.push 1 assert_equal [1], d.map { |x| x } d.push 2 assert_equal [1, 2], d.map { |x| x } d.push 3 assert_equal [1, 2, 3], d.map { |x| x } end end tins-1.1.0/tests/date_dummy_test.rb0000644000004100000410000000135212321542746017403 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class DateDummyTest < Test::Unit::TestCase require 'tins/xt/date_dummy' require 'date' def test_date_dummy date = Date.parse('2009-09-09') assert_not_equal date, Date.today Date.dummy = date assert_equal date, Date.today Date.dummy = nil assert_not_equal date, Date.today end def test_date_dummy_block date = Date.parse('2009-09-09') assert_not_equal date, Date.today Date.dummy date do assert_equal date, Date.today Date.dummy date + 1 do assert_equal date + 1, Date.today end assert_equal date, Date.today end assert_not_equal date, Date.today end end end tins-1.1.0/tests/go_test.rb0000644000004100000410000000242512321542746015662 0ustar www-datawww-datarequire 'test_helper' require 'tins/go' module Tins class GoTest < Test::Unit::TestCase include Tins::GO def test_empty_string r = go '', args = %w[a b c] assert_equal({}, r) assert_equal %w[a b c], args end def test_empty_args r = go 'ab:', args = [] assert_equal({ 'a' => false, 'b' => nil }, r) assert_equal [], args end def test_simple r = go 'ab:', args = %w[-b hello -a -c rest] assert_equal({ 'a' => 1, 'b' => 'hello' }, r) assert_equal %w[-c rest], args end def test_complex r = go 'ab:', args = %w[-a -b hello -a -bworld -c rest] assert_equal({ 'a' => 2, 'b' => 'hello' }, r) assert_equal %w[hello world], r['b'].to_a assert_equal %w[-c rest], args end def test_complex2 r = go 'ab:', args = %w[-b hello -aa -b world -c rest] assert_equal({ 'a' => 2, 'b' => 'hello' }, r) assert_equal %w[hello world], r['b'].to_a assert_equal %w[-c rest], args end def test_complex_frozen args = %w[-b hello -aa -b world -c rest] args = args.map(&:freeze) r = go 'ab:', args assert_equal({ 'a' => 2, 'b' => 'hello' }, r) assert_equal %w[hello world], r['b'].to_a assert_equal %w[-c rest], args end end end tins-1.1.0/tests/string_camelize_test.rb0000644000004100000410000000142712321542746020435 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class StringCamelizeTest < Test::Unit::TestCase def test_camelize assert_equal 'FooBar', 'foo_bar'.camelize assert_equal 'FooBar', 'foo_bar'.camelize(:upper) assert_equal 'FooBar', 'foo_bar'.camelize(true) assert_equal 'fooBar', 'foo_bar'.camelize(:lower) assert_equal 'fooBar', 'foo_bar'.camelize(false) assert_equal 'FooBar', 'foo_bar'.camelcase assert_equal 'Foo::Bar', 'foo/bar'.camelize assert_equal 'Foo::Bar', 'foo/bar'.camelize(:upper) assert_equal 'Foo::Bar', 'foo/bar'.camelize(true) assert_equal 'foo::Bar', 'foo/bar'.camelize(:lower) assert_equal 'foo::Bar', 'foo/bar'.camelize(false) assert_equal 'Foo::Bar', 'foo/bar'.camelcase end end end tins-1.1.0/tests/time_dummy_test.rb0000644000004100000410000000135412321542746017426 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class TimeDummyTest < Test::Unit::TestCase require 'tins/xt/time_dummy' require 'time' def test_time_dummy time = Time.parse('2009-09-09 21:09:09') assert_not_equal time, Time.now Time.dummy = time assert_equal time, Time.now Time.dummy = nil assert_not_equal time, Time.now end def test_time_dummy_block time = Time.parse('2009-09-09 21:09:09') assert_not_equal time, Time.now Time.dummy time do assert_equal time, Time.now Time.dummy time + 1 do assert_equal time + 1, Time.now end assert_equal time, Time.now end assert_not_equal time, Time.now end end end tins-1.1.0/tests/named_set_test.rb0000644000004100000410000000053312321542746017212 0ustar www-datawww-datarequire 'test_helper' require 'tins/named_set' module Tins class NamedSetTest < Test::Unit::TestCase class ThingsTodo < Tins::NamedSet end def test_named_set s = ThingsTodo.new('list') assert_equal 'list', s.name s << 'Get up' s << 'Shower' s << 'Shave' assert_equal 3, s.size end end end tins-1.1.0/tests/string_version_test.rb0000644000004100000410000000154612321542746020333 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class StringVersionTest < Test::Unit::TestCase def test_comparison assert_operator '1.2'.version, :<, '1.3'.version assert_operator '1.3'.version, :>, '1.2'.version assert_operator '1.2'.version, :<=, '1.2'.version assert_operator '1.2'.version, :>=, '1.2'.version assert_operator '1.2'.version, :==, '1.2'.version end def test_change s = '1.2' s.version.revision = 1 assert_equal '1.2.0.1', s s.version.revision += 1 assert_equal '1.2.0.2', s s.version.succ! assert_equal '1.2.0.3', s s.version.pred! assert_equal '1.2.0.2', s assert_raise(ArgumentError) { s.version.build -= 1 } s.version.major = 2 assert_equal '2.2.0.2', s s.version.minor = 1 assert_equal '2.1.0.2', s end end end tins-1.1.0/tests/round_test.rb0000644000004100000410000000167412321542746016411 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class RoundTest < Test::Unit::TestCase def test_standard assert_equal(1, 1.round) assert_equal(-1, -1.round) assert_equal(2, 1.5.round) assert_kind_of Integer, 1.5.round assert_equal(-1, -1.4.round) assert_equal(-2, -1.5.round) end def test_inclusion assert_equal(10, 12.round(-1)) assert_kind_of Integer, 12.round(-1) assert_equal(-10, -12.round(-1)) assert_raises(ArgumentError) { 12.round(-2) } assert_raises(ArgumentError) { -12.round(-2) } assert_in_delta(1.6, 1.55.round(1), 1E-1) assert_kind_of Float, 1.55.round(1) assert_equal(2, 1.55.round(0)) assert_in_delta(-1.5, -1.45.round(1), 1E-1) assert_equal(-1, -1.45.round(0)) assert_in_delta(-1.6, -1.55.round(1), 1E-1) assert_equal(-2, -1.55.round(0)) assert_in_delta(-1.55, -1.55.round(999), 1E-2) end end end tins-1.1.0/tests/dynamic_scope_test.rb0000644000004100000410000000144712321542746020075 0ustar www-datawww-datarequire 'test_helper' require 'tins' class DynamicScopeTest < Test::Unit::TestCase include Tins::DynamicScope def test_dynamic_scoping assert_raise(NameError) { foo } assert_equal false, dynamic_defined?(:foo) dynamic_scope do assert_raise(NameError) { foo } assert_equal false, dynamic_defined?(:foo) self.foo = 1 assert_equal 1, foo assert_equal true, dynamic_defined?(:foo) dynamic_scope do assert_equal 1, foo assert_equal true, dynamic_defined?(:foo) self.foo = 2 assert_equal 2, foo dynamic_scope do assert_equal 2, foo end assert_equal 2, foo end assert_equal 1, foo end assert_equal false, dynamic_defined?(:foo) assert_raise(NameError) { foo } end end tins-1.1.0/tests/to_test.rb0000644000004100000410000000124112321542746015672 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt/to' module Tins class ToTest < Test::Unit::TestCase def test_to_removing_leading_spaces doc = to(<<-end) hello, world end assert_equal "hello, world\n", doc end def test_to_removing_leading_spaces_depending_on_first_line doc = to(<<-end) hello world, how are things? end assert_equal "hello\n world,\n how are\n things?\n", doc end def test_to_not_removing_empty_lines doc = to(<<-end) hello, world another line end assert_equal "hello, world\n\nanother line\n", doc end end end tins-1.1.0/tests/string_underscore_test.rb0000644000004100000410000000037112321542746021012 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class StringUnderscoreTest < Test::Unit::TestCase def test_underscore assert_equal 'foo_bar', 'FooBar'.underscore assert_equal 'foo/bar', 'Foo::Bar'.underscore end end end tins-1.1.0/tests/method_description_test.rb0000644000004100000410000000246512321542746021144 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' if RUBY_VERSION >= "1.9" module Tins class MethodDescriptionTest < Test::Unit::TestCase class A def foo end def self.foo end end def test_static_nonstatic assert_equal 'Tins::MethodDescriptionTest::A#foo()', A.instance_method(:foo).to_s assert_equal '#', A.instance_method(:foo).inspect assert_equal 'Tins::MethodDescriptionTest::A.foo()', A.method(:foo).to_s assert_equal '#', A.method(:foo).inspect end class B def foo(x, y = 1, *r, &b) end end def test_standard_parameters assert_equal 'Tins::MethodDescriptionTest::B#foo(x,y=,*r,&b)', B.instance_method(:foo).to_s end if RUBY_VERSION >= "2.0" eval %{ class C def foo(x, k: true, &b) end def bar(x, **k, &b) end end def test_keyword_parameters assert_equal 'Tins::MethodDescriptionTest::C#foo(x,k:,&b)', C.instance_method(:foo).to_s assert_equal 'Tins::MethodDescriptionTest::C#bar(x,**k,&b)', C.instance_method(:bar).to_s end } end end end end tins-1.1.0/tests/if_predicate_test.rb0000644000004100000410000000034712321542746017674 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class IfPredicateTest def test_if_predicate assert_equal :foo, true.if? && :foo assert_nil false.if? && :foo assert_nil nil.if? && :foo end end end tins-1.1.0/tests/generator_test.rb0000644000004100000410000000175612321542746017251 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class GeneratorTest < Test::Unit::TestCase def setup @numeric = [ 1, 2, 3 ] @string = %w[a b c] @chars = 'abc' end def test_generator g = Tins::Generator[@numeric, @string] assert_equal 2, g.size g.add_dimension(@chars, :each_byte) assert_equal 3, g.size assert_equal\ [[1, "a", 97], [1, "a", 98], [1, "a", 99], [1, "b", 97], [1, "b", 98], [1, "b", 99], [1, "c", 97], [1, "c", 98], [1, "c", 99], [2, "a", 97], [2, "a", 98], [2, "a", 99], [2, "b", 97], [2, "b", 98], [2, "b", 99], [2, "c", 97], [2, "c", 98], [2, "c", 99], [3, "a", 97], [3, "a", 98], [3, "a", 99], [3, "b", 97], [3, "b", 98], [3, "b", 99], [3, "c", 97], [3, "c", 98], [3, "c", 99]], g.to_a end end end tins-1.1.0/tests/date_time_dummy_test.rb0000644000004100000410000000155612321542746020427 0ustar www-datawww-datarequire 'test_helper' require 'tins' module Tins class DateTimeDummyTest < Test::Unit::TestCase require 'tins/xt/date_time_dummy' require 'date' def test_time_dummy date_time = DateTime.parse('2009-09-09 21:09:09') assert_not_equal date_time, DateTime.now DateTime.dummy = date_time assert_equal date_time, DateTime.now DateTime.dummy = nil assert_not_equal date_time, DateTime.now end def test_time_dummy_block date_time = DateTime.parse('2009-09-09 21:09:09') assert_not_equal date_time, DateTime.now DateTime.dummy date_time do assert_equal date_time, DateTime.now DateTime.dummy date_time + 1 do assert_equal date_time + 1, DateTime.now end assert_equal date_time, DateTime.now end assert_not_equal date_time, DateTime.now end end end tins-1.1.0/tests/named_test.rb0000644000004100000410000000151112321542746016334 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class NamedTest < Test::Unit::TestCase def test_named_simple a = [ 1, 2, 3 ] a.named(:plus1, :map) { |x| x + 1 } assert_equal [ 2, 3, 4 ], a.plus1 Array.named(:odd, :select) { |x| x % 2 == 1 } assert_equal [ 3 ], a.plus1.odd end if RUBY_VERSION >= '1.9' def foo(x, y, &block) block.call x * y end def test_more_complex Object.named(:foo_with_block, :foo) do |z| z ** 2 end assert_equal foo(2, 3) { |z| z ** 2 }, foo_with_block(2, 3) Object.named(:foo_23, :foo, 2, 3) assert_equal foo(2, 3) { |z| z ** 2 }, foo_23 { |z| z ** 2 } Object.named(:foo_2, :foo, 2) assert_equal foo(2, 3) { |z| z ** 2 }, foo_2(3) { |z| z ** 2 } end end end end tins-1.1.0/tests/find_test.rb0000644000004100000410000000772512321542746016205 0ustar www-datawww-datarequire 'test_helper' require 'tins/find' require 'fileutils' require 'tempfile' module Tins class FindTest < Test::Unit::TestCase include Tins::Find include FileUtils def setup mkdir_p @work_dir = File.join(Dir.tmpdir, "test.#$$") end def teardown rm_rf @work_dir end def test_raising_errors assert_equal [], find(File.join(@work_dir, 'nix'), :raise_errors => false).to_a assert_equal [], find(File.join(@work_dir, 'nix')).to_a assert_raise(Errno::ENOENT) do find(File.join(@work_dir, 'nix'), :raise_errors => true).to_a end end def test_showing_hidden touch file = File.join(@work_dir, '.foo') assert_equal [ @work_dir ], find(@work_dir, :show_hidden => false).to_a assert_equal [ @work_dir, file ], find(@work_dir).to_a assert_equal [ @work_dir, file ], find(@work_dir, :show_hidden => true).to_a end def test_check_directory_without_access # do not run this test on JRuby omit_if(RUBY_PLATFORM =~ /java/, "Can't run the test on JRuby") # do not run this test if we're root, as it will fail. omit_if(Process::UID.eid == 0, "Can't run the test as root") begin mkdir_p directory1 = File.join(@work_dir, 'foo') mkdir_p directory2 = File.join(directory1, 'bar') touch file = File.join(directory2, 'file') chmod 0, directory2 assert_equal [ @work_dir, directory1, directory2 ], find(@work_dir, :raise_errors => false).to_a assert_equal [ @work_dir, directory1, directory2 ], find(@work_dir).to_a assert_raise(Errno::EACCES) do find(@work_dir, :raise_errors => true).to_a end ensure File.exist?(directory2) and chmod 0777, directory2 end end def test_follow_symlinks mkdir_p directory1 = File.join(@work_dir, 'foo1') mkdir_p directory2 = File.join(@work_dir, 'foo2') mkdir_p directory3 = File.join(directory1, 'bar') touch file = File.join(directory3, 'foo') ln_s directory3, link = File.join(directory2, 'baz') assert_equal [ directory2, link ], find(directory2, :follow_symlinks => false).to_a assert_equal [ directory2, link, linked = File.join(link, 'foo') ], find(directory2).to_a assert_equal [ directory2, link, linked ], find(directory2, :follow_symlinks => true).to_a end def test_path_file File.open(File.join(@work_dir, 'foo'), 'w') do |f| f.print "hello" f.fsync assert_equal "hello", find(@work_dir).select { |f| f.stat.file? }.first.file.read end end def test_path_extension finder = Tins::Find::Finder.new f = File.open(path = File.join(@work_dir, 'foo.bar'), 'w') ln_s path, path2 = File.join(@work_dir, 'foo2.bar') path2 = finder.prepare_path path2 path = finder.prepare_path path assert_true path.exist? assert_true path.file? assert_false path.directory? assert_true finder.prepare_path(Dir.pwd).directory? assert_equal Pathname.new(path), path.pathname assert_equal 'bar', path.suffix assert_true path2.lstat.symlink? ensure f and rm_f f.path end def test_suffix finder = Tins::Find::Finder.new(:suffix => 'bar') f = File.open(fpath = File.join(@work_dir, 'foo.bar'), 'w') g = File.open(gpath = File.join(@work_dir, 'foo.baz'), 'w') fpath = finder.prepare_path fpath gpath = finder.prepare_path gpath assert_true finder.visit_path?(fpath) assert_false finder.visit_path?(gpath) finder.suffix = nil assert_true finder.visit_path?(fpath) assert_true finder.visit_path?(gpath) ensure f and rm_f f.path g and rm_f g.path end def test_prune mkdir_p directory1 = File.join(@work_dir, 'foo1') mkdir_p directory2 = File.join(@work_dir, 'foo2') result = [] find(@work_dir) { |f| f =~ /foo2\z/ and prune; result << f } assert_equal [ @work_dir, directory1 ], result end end end tins-1.1.0/tests/proc_compose_test.rb0000644000004100000410000000115012321542746017737 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt' module Tins class ProcComposeTest < Test::Unit::TestCase def test_proc_compose_simple f = lambda { |x| 2 * x } g = lambda { |x| x + 1 } assert_equal 6, (f * g).call(2) end def test_proc_compose_more_complex f = lambda { |x, y| 2 * x + y * 3 } g = lambda { |x| x + 1 } if RUBY_VERSION >= "1.9" assert_raise(ArgumentError) { (f * g).call(2, 3) } else assert_raise(TypeError) { (f * g).call(2, 3) } end d = lambda { |x| [ x, x ] } assert_equal 15, (f * d * g).call(2) end end end tins-1.1.0/tests/proc_prelude_test.rb0000644000004100000410000000324512321542746017741 0ustar www-datawww-datarequire 'test_helper' require 'tins/xt/proc_prelude' module Tins class ProcPreludeTest < Test::Unit::TestCase def test_apply assert_equal 42, Proc.apply { |x, y, z| x ** 2 + y ** 3 + z ** 5 }.call([3, 1, 2]) end class Person def initialize(name) @name = name end attr_reader :name end def test_map_apply ps = %w[anne bernd christian].map { |n| Person.new(n) } i = 0 assert_equal %w[ anne1 bernd2 christian3 ], ps.inject([], &Proc.map_apply(:name) { |s, n| s << "#{n}#{i += 1}" }) end def test_call def (o = Object.new).foo :foo end assert_equal :foo, Proc.call(o) { foo } end def test_array assert_equal [1,2,3], Proc.array.call(1,2,3) end def test_first assert_equal 1, Proc.first.call(1,2,3) assert_equal 1, Proc.head.call(1,2,3) end def test_second assert_equal 2, Proc.second.call(1,2,3) end def test_tail assert_equal [ 2, 3 ], Proc.tail.call(1,2,3) end def test_last assert_equal 3, Proc.last.call(1,2,3) end def test_rotate assert_equal [ 2, 3, 1 ], Proc.rotate.call(1,2,3) assert_equal [ 2, 1 ], Proc.swap.call(1,2) end def test_id1 assert_equal :foo, Proc.id1.call(:foo) end def test_const assert_equal :baz, Proc.const(:baz).call(:foo, :bar) assert_equal :baz, Proc.const { :baz }.call(:foo, :bar) end def test_nth assert_equal 2, Proc.nth(1).call(1,2,3) end def square(x) x ** 2 end def test_from assert_equal [ 1, 4, 9 ], [ 1, 2, 3 ].map(&Proc.from{:square}) end end end tins-1.1.0/tests/scope_test.rb0000644000004100000410000000135312321542746016365 0ustar www-datawww-datarequire 'test_helper' require 'tins' class ScopeTest < Test::Unit::TestCase include Tins::Scope def test_default_scope scope_block(:foo) do assert_equal [ :foo ], scope scope_block(:bar) do assert_equal [ :foo, :bar ], scope scope.push :baz assert_equal [ :foo, :bar ], scope end end end def test_two_scopes scope_block(:foo, :my_scope) do assert_equal [ :foo ], scope(:my_scope) scope_block(:baz) do scope_block(:bar, :my_scope) do assert_equal [ :foo, :bar ], scope(:my_scope) scope.push(:baz, :my_scope) assert_equal [ :foo, :bar ], scope(:my_scope) assert_equal [ :baz ], scope end end end end end tins-1.1.0/tests/concern_test.rb0000644000004100000410000000070712321542746016705 0ustar www-datawww-datarequire 'test_helper' require 'tins' class ConcernTest < Test::Unit::TestCase module AC extend Tins::Concern included do $included = self end def foo :foo end module ClassMethods def bar :bar end end end $included = nil class A include AC end def test_concern a = A.new assert_equal A, $included assert_equal :foo, a.foo assert_equal :bar, A.bar end end tins-1.1.0/tins.gemspec0000644000004100000410000003064512321542746015056 0ustar www-datawww-data# -*- encoding: utf-8 -*- # stub: tins 1.1.0 ruby lib Gem::Specification.new do |s| s.name = "tins" s.version = "1.1.0" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.require_paths = ["lib"] s.authors = ["Florian Frank"] s.date = "2014-04-07" s.description = "All the stuff that isn't good/big enough for a real library." s.email = "flori@ping.de" s.extra_rdoc_files = ["README.rdoc", "lib/dslkit.rb", "lib/dslkit/polite.rb", "lib/dslkit/rude.rb", "lib/spruz.rb", "lib/tins.rb", "lib/tins/alias.rb", "lib/tins/annotate.rb", "lib/tins/ask_and_send.rb", "lib/tins/attempt.rb", "lib/tins/bijection.rb", "lib/tins/concern.rb", "lib/tins/count_by.rb", "lib/tins/date_dummy.rb", "lib/tins/date_time_dummy.rb", "lib/tins/deep_const_get.rb", "lib/tins/deep_dup.rb", "lib/tins/dslkit.rb", "lib/tins/extract_last_argument_options.rb", "lib/tins/file_binary.rb", "lib/tins/find.rb", "lib/tins/generator.rb", "lib/tins/go.rb", "lib/tins/hash_symbolize_keys_recursive.rb", "lib/tins/hash_union.rb", "lib/tins/if_predicate.rb", "lib/tins/limited.rb", "lib/tins/lines_file.rb", "lib/tins/memoize.rb", "lib/tins/method_description.rb", "lib/tins/minimize.rb", "lib/tins/module_group.rb", "lib/tins/named_set.rb", "lib/tins/null.rb", "lib/tins/once.rb", "lib/tins/p.rb", "lib/tins/partial_application.rb", "lib/tins/proc_compose.rb", "lib/tins/proc_prelude.rb", "lib/tins/range_plus.rb", "lib/tins/require_maybe.rb", "lib/tins/responding.rb", "lib/tins/rotate.rb", "lib/tins/round.rb", "lib/tins/secure_write.rb", "lib/tins/sexy_singleton.rb", "lib/tins/shuffle.rb", "lib/tins/string_byte_order_mark.rb", "lib/tins/string_camelize.rb", "lib/tins/string_underscore.rb", "lib/tins/string_version.rb", "lib/tins/subhash.rb", "lib/tins/terminal.rb", "lib/tins/thread_local.rb", "lib/tins/time_dummy.rb", "lib/tins/time_freezer.rb", "lib/tins/to.rb", "lib/tins/to_proc.rb", "lib/tins/token.rb", "lib/tins/uniq_by.rb", "lib/tins/version.rb", "lib/tins/write.rb", "lib/tins/xt.rb", "lib/tins/xt/annotate.rb", "lib/tins/xt/ask_and_send.rb", "lib/tins/xt/attempt.rb", "lib/tins/xt/blank.rb", "lib/tins/xt/concern.rb", "lib/tins/xt/count_by.rb", "lib/tins/xt/date_dummy.rb", "lib/tins/xt/date_time_dummy.rb", "lib/tins/xt/deep_const_get.rb", "lib/tins/xt/deep_dup.rb", "lib/tins/xt/dslkit.rb", "lib/tins/xt/extract_last_argument_options.rb", "lib/tins/xt/file_binary.rb", "lib/tins/xt/full.rb", "lib/tins/xt/hash_symbolize_keys_recursive.rb", "lib/tins/xt/hash_union.rb", "lib/tins/xt/if_predicate.rb", "lib/tins/xt/irb.rb", "lib/tins/xt/method_description.rb", "lib/tins/xt/named.rb", "lib/tins/xt/null.rb", "lib/tins/xt/p.rb", "lib/tins/xt/partial_application.rb", "lib/tins/xt/proc_compose.rb", "lib/tins/xt/proc_prelude.rb", "lib/tins/xt/range_plus.rb", "lib/tins/xt/require_maybe.rb", "lib/tins/xt/responding.rb", "lib/tins/xt/rotate.rb", "lib/tins/xt/round.rb", "lib/tins/xt/secure_write.rb", "lib/tins/xt/sexy_singleton.rb", "lib/tins/xt/shuffle.rb", "lib/tins/xt/string.rb", "lib/tins/xt/string_byte_order_mark.rb", "lib/tins/xt/string_camelize.rb", "lib/tins/xt/string_underscore.rb", "lib/tins/xt/string_version.rb", "lib/tins/xt/subhash.rb", "lib/tins/xt/symbol_to_proc.rb", "lib/tins/xt/time_dummy.rb", "lib/tins/xt/to.rb", "lib/tins/xt/uniq_by.rb", "lib/tins/xt/write.rb"] s.files = [".gitignore", ".travis.yml", "COPYING", "Gemfile", "README.rdoc", "Rakefile", "TODO", "VERSION", "examples/add_one.png", "examples/add_one.stm", "examples/bb3.png", "examples/bb3.stm", "examples/bb3_19.stm", "examples/concatenate_compare.mtm", "examples/concatenate_compare.png", "examples/concatenate_compare_19.mtm", "examples/length_difference.mtm", "examples/length_difference.png", "examples/length_difference_19.mtm", "examples/let.rb", "examples/mail.rb", "examples/minsky.rb", "examples/multiply.reg", "examples/null_pattern.rb", "examples/ones_difference-mtm.png", "examples/ones_difference-stm.png", "examples/ones_difference.mtm", "examples/ones_difference.stm", "examples/ones_difference_19.mtm", "examples/ones_difference_19.stm", "examples/prefix-equals-suffix-reversed-with-infix.png", "examples/prefix-equals-suffix-reversed-with-infix.stm", "examples/prefix-equals-suffix-reversed-with-infix_19.stm", "examples/recipe.rb", "examples/recipe2.rb", "examples/recipe_common.rb", "examples/subtract.reg", "examples/turing-graph.rb", "examples/turing.rb", "lib/dslkit.rb", "lib/dslkit/polite.rb", "lib/dslkit/rude.rb", "lib/spruz", "lib/spruz.rb", "lib/tins.rb", "lib/tins/alias.rb", "lib/tins/annotate.rb", "lib/tins/ask_and_send.rb", "lib/tins/attempt.rb", "lib/tins/bijection.rb", "lib/tins/concern.rb", "lib/tins/count_by.rb", "lib/tins/date_dummy.rb", "lib/tins/date_time_dummy.rb", "lib/tins/deep_const_get.rb", "lib/tins/deep_dup.rb", "lib/tins/dslkit.rb", "lib/tins/extract_last_argument_options.rb", "lib/tins/file_binary.rb", "lib/tins/find.rb", "lib/tins/generator.rb", "lib/tins/go.rb", "lib/tins/hash_symbolize_keys_recursive.rb", "lib/tins/hash_union.rb", "lib/tins/if_predicate.rb", "lib/tins/limited.rb", "lib/tins/lines_file.rb", "lib/tins/memoize.rb", "lib/tins/method_description.rb", "lib/tins/minimize.rb", "lib/tins/module_group.rb", "lib/tins/named_set.rb", "lib/tins/null.rb", "lib/tins/once.rb", "lib/tins/p.rb", "lib/tins/partial_application.rb", "lib/tins/proc_compose.rb", "lib/tins/proc_prelude.rb", "lib/tins/range_plus.rb", "lib/tins/require_maybe.rb", "lib/tins/responding.rb", "lib/tins/rotate.rb", "lib/tins/round.rb", "lib/tins/secure_write.rb", "lib/tins/sexy_singleton.rb", "lib/tins/shuffle.rb", "lib/tins/string_byte_order_mark.rb", "lib/tins/string_camelize.rb", "lib/tins/string_underscore.rb", "lib/tins/string_version.rb", "lib/tins/subhash.rb", "lib/tins/terminal.rb", "lib/tins/thread_local.rb", "lib/tins/time_dummy.rb", "lib/tins/time_freezer.rb", "lib/tins/to.rb", "lib/tins/to_proc.rb", "lib/tins/token.rb", "lib/tins/uniq_by.rb", "lib/tins/version.rb", "lib/tins/write.rb", "lib/tins/xt.rb", "lib/tins/xt/annotate.rb", "lib/tins/xt/ask_and_send.rb", "lib/tins/xt/attempt.rb", "lib/tins/xt/blank.rb", "lib/tins/xt/concern.rb", "lib/tins/xt/count_by.rb", "lib/tins/xt/date_dummy.rb", "lib/tins/xt/date_time_dummy.rb", "lib/tins/xt/deep_const_get.rb", "lib/tins/xt/deep_dup.rb", "lib/tins/xt/dslkit.rb", "lib/tins/xt/extract_last_argument_options.rb", "lib/tins/xt/file_binary.rb", "lib/tins/xt/full.rb", "lib/tins/xt/hash_symbolize_keys_recursive.rb", "lib/tins/xt/hash_union.rb", "lib/tins/xt/if_predicate.rb", "lib/tins/xt/irb.rb", "lib/tins/xt/method_description.rb", "lib/tins/xt/named.rb", "lib/tins/xt/null.rb", "lib/tins/xt/p.rb", "lib/tins/xt/partial_application.rb", "lib/tins/xt/proc_compose.rb", "lib/tins/xt/proc_prelude.rb", "lib/tins/xt/range_plus.rb", "lib/tins/xt/require_maybe.rb", "lib/tins/xt/responding.rb", "lib/tins/xt/rotate.rb", "lib/tins/xt/round.rb", "lib/tins/xt/secure_write.rb", "lib/tins/xt/sexy_singleton.rb", "lib/tins/xt/shuffle.rb", "lib/tins/xt/string.rb", "lib/tins/xt/string_byte_order_mark.rb", "lib/tins/xt/string_camelize.rb", "lib/tins/xt/string_underscore.rb", "lib/tins/xt/string_version.rb", "lib/tins/xt/subhash.rb", "lib/tins/xt/symbol_to_proc.rb", "lib/tins/xt/time_dummy.rb", "lib/tins/xt/to.rb", "lib/tins/xt/uniq_by.rb", "lib/tins/xt/write.rb", "tests/annotate_test.rb", "tests/ask_and_send_test.rb", "tests/attempt_test.rb", "tests/bijection_test.rb", "tests/blank_full_test.rb", "tests/concern_test.rb", "tests/count_by_test.rb", "tests/date_dummy_test.rb", "tests/date_time_dummy_test.rb", "tests/deep_const_get_test.rb", "tests/deep_dup_test.rb", "tests/dslkit_test.rb", "tests/dynamic_scope_test.rb", "tests/extract_last_argument_options_test.rb", "tests/file_binary_test.rb", "tests/find_test.rb", "tests/from_module_test.rb", "tests/generator_test.rb", "tests/go_test.rb", "tests/hash_symbolize_keys_recursive_test.rb", "tests/hash_union_test.rb", "tests/if_predicate_test.rb", "tests/limited_test.rb", "tests/lines_file_test.rb", "tests/memoize_test.rb", "tests/method_description_test.rb", "tests/minimize_test.rb", "tests/module_group_test.rb", "tests/named_set_test.rb", "tests/named_test.rb", "tests/null_test.rb", "tests/p_test.rb", "tests/partial_application_test.rb", "tests/proc_compose_test.rb", "tests/proc_prelude_test.rb", "tests/range_plus_test.rb", "tests/require_maybe_test.rb", "tests/responding_test.rb", "tests/rotate_test.rb", "tests/round_test.rb", "tests/scope_test.rb", "tests/secure_write_test.rb", "tests/sexy_singleton_test.rb", "tests/shuffle_test.rb", "tests/string_byte_order_mark_test.rb", "tests/string_camelize_test.rb", "tests/string_underscore_test.rb", "tests/string_version_test.rb", "tests/subhash_test.rb", "tests/test_helper.rb", "tests/time_dummy_test.rb", "tests/time_freezer_test.rb", "tests/to_test.rb", "tests/token_test.rb", "tests/uniq_by_test.rb", "tins.gemspec"] s.homepage = "http://flori.github.com/tins" s.licenses = ["MIT"] s.rdoc_options = ["--title", "Tins - Useful stuff.", "--main", "README.rdoc"] s.rubygems_version = "2.2.2" s.summary = "Useful stuff." s.test_files = ["tests/annotate_test.rb", "tests/ask_and_send_test.rb", "tests/attempt_test.rb", "tests/bijection_test.rb", "tests/blank_full_test.rb", "tests/concern_test.rb", "tests/count_by_test.rb", "tests/date_dummy_test.rb", "tests/date_time_dummy_test.rb", "tests/deep_const_get_test.rb", "tests/deep_dup_test.rb", "tests/dslkit_test.rb", "tests/dynamic_scope_test.rb", "tests/extract_last_argument_options_test.rb", "tests/file_binary_test.rb", "tests/find_test.rb", "tests/from_module_test.rb", "tests/generator_test.rb", "tests/go_test.rb", "tests/hash_symbolize_keys_recursive_test.rb", "tests/hash_union_test.rb", "tests/if_predicate_test.rb", "tests/limited_test.rb", "tests/lines_file_test.rb", "tests/memoize_test.rb", "tests/method_description_test.rb", "tests/minimize_test.rb", "tests/module_group_test.rb", "tests/named_set_test.rb", "tests/named_test.rb", "tests/null_test.rb", "tests/p_test.rb", "tests/partial_application_test.rb", "tests/proc_compose_test.rb", "tests/proc_prelude_test.rb", "tests/range_plus_test.rb", "tests/require_maybe_test.rb", "tests/responding_test.rb", "tests/rotate_test.rb", "tests/round_test.rb", "tests/scope_test.rb", "tests/secure_write_test.rb", "tests/sexy_singleton_test.rb", "tests/shuffle_test.rb", "tests/string_byte_order_mark_test.rb", "tests/string_camelize_test.rb", "tests/string_underscore_test.rb", "tests/string_version_test.rb", "tests/subhash_test.rb", "tests/test_helper.rb", "tests/time_dummy_test.rb", "tests/time_freezer_test.rb", "tests/to_test.rb", "tests/token_test.rb", "tests/uniq_by_test.rb", "tests/annotate_test.rb", "tests/ask_and_send_test.rb", "tests/attempt_test.rb", "tests/bijection_test.rb", "tests/blank_full_test.rb", "tests/concern_test.rb", "tests/count_by_test.rb", "tests/date_dummy_test.rb", "tests/date_time_dummy_test.rb", "tests/deep_const_get_test.rb", "tests/deep_dup_test.rb", "tests/dslkit_test.rb", "tests/dynamic_scope_test.rb", "tests/extract_last_argument_options_test.rb", "tests/file_binary_test.rb", "tests/find_test.rb", "tests/from_module_test.rb", "tests/generator_test.rb", "tests/go_test.rb", "tests/hash_symbolize_keys_recursive_test.rb", "tests/hash_union_test.rb", "tests/if_predicate_test.rb", "tests/limited_test.rb", "tests/lines_file_test.rb", "tests/memoize_test.rb", "tests/method_description_test.rb", "tests/minimize_test.rb", "tests/module_group_test.rb", "tests/named_set_test.rb", "tests/named_test.rb", "tests/null_test.rb", "tests/p_test.rb", "tests/partial_application_test.rb", "tests/proc_compose_test.rb", "tests/proc_prelude_test.rb", "tests/range_plus_test.rb", "tests/require_maybe_test.rb", "tests/responding_test.rb", "tests/rotate_test.rb", "tests/round_test.rb", "tests/scope_test.rb", "tests/secure_write_test.rb", "tests/sexy_singleton_test.rb", "tests/shuffle_test.rb", "tests/string_byte_order_mark_test.rb", "tests/string_camelize_test.rb", "tests/string_underscore_test.rb", "tests/string_version_test.rb", "tests/subhash_test.rb", "tests/time_dummy_test.rb", "tests/time_freezer_test.rb", "tests/to_test.rb", "tests/token_test.rb", "tests/uniq_by_test.rb"] if s.respond_to? :specification_version then s.specification_version = 4 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then s.add_development_dependency(%q, ["~> 1.0.0"]) s.add_development_dependency(%q, ["~> 2.5"]) else s.add_dependency(%q, ["~> 1.0.0"]) s.add_dependency(%q, ["~> 2.5"]) end else s.add_dependency(%q, ["~> 1.0.0"]) s.add_dependency(%q, ["~> 2.5"]) end end tins-1.1.0/README.rdoc0000644000004100000410000000041612321542746014333 0ustar www-datawww-data= Tins - Useful tools library in Ruby == Description Non yet. == Download The homepage of this library is located at * http://flori.github.com/tins == Author Florian Frank mailto:flori@ping.de == License This software is licensed under the MIT (Expat) license. tins-1.1.0/.travis.yml0000644000004100000410000000035012321542746014633 0ustar www-datawww-datarvm: - 1.8.7 - 1.9.2 - 1.9.3 - 2.0.0 - 2.1.0 - ruby-head - ree - rbx-18mode - rbx-19mode - jruby-18mode - jruby-19mode matrix: allow_failures: - rvm: ruby-head - rvm: rbx-18mode - rvm: rbx-19mode tins-1.1.0/lib/0000755000004100000410000000000012321542746013272 5ustar www-datawww-datatins-1.1.0/lib/spruz.rb0000644000004100000410000000004412321542746015000 0ustar www-datawww-datarequire 'tins' require 'tins/alias' tins-1.1.0/lib/tins/0000755000004100000410000000000012321542746014247 5ustar www-datawww-datatins-1.1.0/lib/tins/file_binary.rb0000644000004100000410000000516512321542746017066 0ustar www-datawww-datarequire 'tins/xt/hash_union' module Tins module FileBinary module Constants SEEK_SET = ::File::SEEK_SET ZERO = "\x00" BINARY = "\x01-\x1f\x7f-\xff" if defined?(::Encoding) ZERO.force_encoding(Encoding::ASCII_8BIT) BINARY.force_encoding(Encoding::ASCII_8BIT) end end class << self # Default options can be queried/set via this hash. attr_accessor :default_options end self.default_options = { :offset => 0, :buffer_size => 2 ** 13, :percentage_binary => 30.0, :percentage_zeros => 0.0, } # Returns true if this file is considered to be binary, false if it is not # considered to be binary, and nil if it was empty. # # A file is considered to be binary if the percentage of zeros exceeds # options[:percentage_zeros] or the percentage of binary bytes # (8-th bit is 1) exceeds options[:percentage_binary] in the # buffer of size options[:buffer_size] that is checked (beginning # from offset options[:offset]). If an option isn't given the one # from FileBinary.default_options is used instead. def binary?(options = {}) options |= FileBinary.default_options old_pos = tell seek options[:offset], Constants::SEEK_SET data = read options[:buffer_size] !data or data.empty? and return nil data_size = data.size data.count(Constants::ZERO).to_f / data_size > options[:percentage_zeros] / 100.0 and return true data.count(Constants::BINARY).to_f / data_size > options[:percentage_binary] / 100.0 ensure old_pos and seek old_pos, Constants::SEEK_SET end # Returns true if FileBinary#binary? returns false, false if # FileBinary#binary? returns true, and nil otherwise. For an explanation of # +options+, see FileBinary#binary?. def ascii?(options = {}) case binary?(options) when true then false when false then true end end def self.included(modul) modul.instance_eval do extend ClassMethods end super end module ClassMethods # Returns true if the file with name +name+ is considered to be binary # using the FileBinary#binary? method. def binary?(name, options = {}) open(name, 'rb') { |f| f.binary?(options) } end # Returns true if the file with name +name+ is considered to be ascii # using the FileBinary#ascii? method. def ascii?(name, options = {}) open(name, 'rb') { |f| f.ascii?(options) } end end end end require 'tins/alias' tins-1.1.0/lib/tins/minimize.rb0000644000004100000410000000336212321542746016421 0ustar www-datawww-datamodule Tins # This module can be mixed into all classes, whose instances respond to the # [] and size-methods, like for example Array. The returned elements from [] # should respond to the succ method. module Minimize # Returns a minimized version of this object, that is successive elements # are substituted with ranges a..b. In the situation ..., x, y,... and y != # x.succ a range x..x is created, to make it easier to iterate over all the # ranges in one run. A small example: # [ 'A', 'B', 'C', 'G', 'K', 'L', 'M' ].minimize # => [ 'A'..'C', 'G'..'G', 'K'..'M' ] # # If the order of the original elements doesn't matter, it's a good idea to # first sort them and then minimize: # [ 5, 1, 4, 2 ].sort.minimize # => [ 1..2, 4..5 ] def minimize result = [] last_index = size - 1 size.times do |i| result << [ self[0] ] if i == 0 if self[i].succ != self[i + 1] or i == last_index result[-1] << self[i] result << [ self[i + 1] ] unless i == last_index end end result.map! { |a, b| a..b } end # First minimizes this object, then calls the replace method with the # result. def minimize! replace minimize end # Invert a minimized version of an object. Some small examples: # [ 'A'..'C', 'G'..'G', 'K'..'M' ].unminimize # => [ 'A', 'B', 'C', 'G', 'K', 'L', 'M' ] # and # [ 1..2, 4..5 ].unminimize # => [ 1, 2, 4, 5 ] def unminimize result = [] for range in self for e in range result << e end end result end # Invert a minimized version of this object in place. def unminimize! replace unminimize end end end require 'tins/alias' tins-1.1.0/lib/tins/proc_compose.rb0000644000004100000410000000042412321542746017264 0ustar www-datawww-datamodule Tins module ProcCompose def compose(other) self.class.new do |*args| if other.respond_to?(:call) call(*other.call(*args)) else call(*other.to_proc.call(*args)) end end end alias * compose end end tins-1.1.0/lib/tins/p.rb0000644000004100000410000000116312321542746015034 0ustar www-datawww-datarequire 'pp' module Tins module P private # Raise a runtime error with the inspected objects +objs+ (obtained by # calling the #inspect method) as their message text. This is useful for # quick debugging. def p!(*objs) raise((objs.size < 2 ? objs.first : objs).inspect) end # Raise a runtime error with the inspected objects +objs+ (obtained by # calling the #pretty_inspect method) as their message text. This is useful # for quick debugging. def pp!(*objs) raise("\n" + (objs.size < 2 ? objs.first : objs).pretty_inspect.chomp) end end end require 'tins/alias' tins-1.1.0/lib/tins/to_proc.rb0000644000004100000410000000026212321542746016241 0ustar www-datawww-datamodule Tins module ToProc # :nocov: def to_proc lambda do |obj, *args| obj.__send__(self, *args[0..-1]) end end end end require 'tins/alias' tins-1.1.0/lib/tins/find.rb0000644000004100000410000000674712321542746015532 0ustar www-datawww-datarequire 'enumerator' require 'pathname' require 'tins/module_group' module Tins module Find EXPECTED_STANDARD_ERRORS = ModuleGroup[ Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG ] class Finder module PathExtension attr_accessor :finder def finder_stat finder.protect_from_errors do finder.follow_symlinks ? File.stat(self) : File.lstat(self) end end def file finder.protect_from_errors do File.new(self) if file? end end def file? finder.protect_from_errors { s = finder_stat and s.file? } end def directory? finder.protect_from_errors { s = finder_stat and s.directory? } end def exist? finder.protect_from_errors { File.exist?(self) } end def stat finder.protect_from_errors { File.stat(self) } end def lstat finder.protect_from_errors { File.lstat(self) } end def pathname Pathname.new(self) end def suffix pathname.extname[1..-1] || '' end end def initialize(opts = {}) @show_hidden = opts.fetch(:show_hidden) { true } @raise_errors = opts.fetch(:raise_errors) { false } @follow_symlinks = opts.fetch(:follow_symlinks) { true } opts[:suffix].full? { |s| @suffix = [*s] } end attr_accessor :show_hidden attr_accessor :raise_errors attr_accessor :follow_symlinks attr_accessor :suffix def visit_path?(path) @suffix.nil? || @suffix.include?(path.suffix) end def find(*paths) block_given? or return enum_for(__method__, *paths) paths.collect! { |d| d.dup } while path = paths.shift path = prepare_path(path) catch(:prune) do stat = path.finder_stat or next visit_path?(path) and yield path if stat.directory? ps = protect_from_errors { Dir.entries(path) } or next ps.sort! ps.reverse_each do |p| next if p == "." or p == ".." next if !@show_hidden && p.start_with?('.') p = File.join(path, p) paths.unshift p.untaint end end end end end def prepare_path(path) path = path.dup.taint path.extend PathExtension path.finder = self path end def protect_from_errors(errors = Find::EXPECTED_STANDARD_ERRORS) yield rescue errors raise_errors and raise return end end # # Calls the associated block with the name of every path and directory # listed as arguments, then recursively on their subdirectories, and so on. # # See the +Find+ module documentation for an example. # def find(*paths, &block) # :yield: path opts = Hash === paths.last ? paths.pop : {} Finder.new(opts).find(*paths, &block) end # # Skips the current path or directory, restarting the loop with the next # entry. If the current path is a directory, that directory will not be # recursively entered. Meaningful only within the block associated with # Find::find. # # See the +Find+ module documentation for an example. # def prune throw :prune end module_function :find, :prune end end tins-1.1.0/lib/tins/proc_prelude.rb0000644000004100000410000000311012321542746017252 0ustar www-datawww-datarequire 'tins/memoize' module Tins module ProcPrelude def apply(&my_proc) my_proc or raise ArgumentError, 'a block argument is required' lambda { |list| my_proc.call(*list) } end def map_apply(my_method, *args, &my_proc) my_proc or raise ArgumentError, 'a block argument is required' lambda { |x, y| my_proc.call(x, y.__send__(my_method, *args)) } end def call(obj, &my_proc) my_proc or raise ArgumentError, 'a block argument is required' obj.instance_eval(&my_proc) end def array lambda { |*list| list } end memoize_function :array, :freeze => true def first lambda { |*list| list.first } end memoize_function :first, :freeze => true alias head first def second lambda { |*list| list[1] } end memoize_function :second, :freeze => true def tail lambda { |*list| list[1..-1] } end memoize_function :tail, :freeze => true def last lambda { |*list| list.last } end memoize_function :last, :freeze => true def rotate(n = 1) lambda { |*list| list.rotate(n) } end alias swap rotate def id1 lambda { |obj| obj } end memoize_function :id1, :freeze => true def const(konst = nil, &my_proc) konst ||= my_proc.call lambda { |*_| konst } end def nth(n) lambda { |*list| list[n] } end def from(&block) my_method, binding = block.call, block.binding my_self = eval 'self', binding lambda { |*list| my_self.__send__(my_method, *list) } end end end tins-1.1.0/lib/tins/partial_application.rb0000644000004100000410000000152112321542746020612 0ustar www-datawww-datamodule Tins module PartialApplication # If this module is included into a Proc (or similar object), it tampers # with its Proc#arity method. def self.included(modul) modul.module_eval do old_arity = instance_method(:arity) define_method(:arity) do @__arity__ or old_arity.bind(self).call end end super end # Create a partial application of this Proc (or similar object) using # _args_ as the already applied arguments. def partial(*args) if args.empty? dup elsif args.size > arity raise ArgumentError, "wrong number of arguments (#{args.size} for #{arity})" else f = lambda { |*b| call(*(args + b)) } f.instance_variable_set :@__arity__, arity - args.size f end end end end require 'tins/alias' tins-1.1.0/lib/tins/xt/0000755000004100000410000000000012321542746014702 5ustar www-datawww-datatins-1.1.0/lib/tins/xt/file_binary.rb0000644000004100000410000000013012321542746017504 0ustar www-datawww-datarequire 'tins/file_binary' module Tins class ::File include FileBinary end end tins-1.1.0/lib/tins/xt/string.rb0000644000004100000410000000025012321542746016532 0ustar www-datawww-datamodule Tins require 'tins/xt/string_camelize' require 'tins/xt/string_underscore' require 'tins/xt/string_version' require 'tins/xt/string_byte_order_mark' end tins-1.1.0/lib/tins/xt/proc_compose.rb0000644000004100000410000000014012321542746017712 0ustar www-datawww-datarequire 'tins/proc_compose' module Tins class ::Proc include Tins::ProcCompose end end tins-1.1.0/lib/tins/xt/p.rb0000644000004100000410000000011512321542746015463 0ustar www-datawww-datarequire 'tins/p' module Tins class ::Object include Tins::P end end tins-1.1.0/lib/tins/xt/proc_prelude.rb0000644000004100000410000000013712321542746017713 0ustar www-datawww-datarequire 'tins/proc_prelude' module Tins class ::Proc extend Tins::ProcPrelude end end tins-1.1.0/lib/tins/xt/blank.rb0000644000004100000410000000174612321542746016326 0ustar www-datawww-datamodule Tins module Blank module Object def blank? respond_to?(:empty?) ? empty? : !self end def present? !blank? end end module NilClass def blank? true end end module FalseClass def blank? true end end module TrueClass def blank? false end end module Array def self.included(modul) modul.module_eval do alias_method :blank?, :empty? end end end module Hash def self.included(modul) modul.module_eval do alias_method :blank?, :empty? end end end module String def blank? self !~ /\S/ end end module Numeric def blank? false end end end unless Object.respond_to?(:blank?) for k in Blank.constants Object.const_get(k).class_eval do include Blank.const_get(k) end end end end tins-1.1.0/lib/tins/xt/partial_application.rb0000644000004100000410000000023712321542746021250 0ustar www-datawww-datarequire 'tins/partial_application' module Tins class ::Proc include PartialApplication end class ::Method include PartialApplication end end tins-1.1.0/lib/tins/xt/to.rb0000644000004100000410000000007612321542746015654 0ustar www-datawww-datamodule Tins class ::Object include ::Tins::To end end tins-1.1.0/lib/tins/xt/string_byte_order_mark.rb0000644000004100000410000000016012321542746021762 0ustar www-datawww-datamodule Tins require 'tins/string_byte_order_mark' class ::String include StringByteOrderMark end end tins-1.1.0/lib/tins/xt/string_version.rb0000644000004100000410000000014212321542746020277 0ustar www-datawww-datamodule Tins require 'tins/string_version' class ::String include StringVersion end end tins-1.1.0/lib/tins/xt/range_plus.rb0000644000004100000410000000033012321542746017362 0ustar www-datawww-datarequire 'tins/range_plus' module Tins class ::Range if method_defined?(:+) warn "#{self}#+ already defined, didn't include at #{__FILE__}:#{__LINE__}" else include RangePlus end end end tins-1.1.0/lib/tins/xt/string_camelize.rb0000644000004100000410000000014312321542746020404 0ustar www-datawww-datamodule Tins require 'tins/string_camelize' class ::String include StringCamelize end end tins-1.1.0/lib/tins/xt/hash_union.rb0000644000004100000410000000032612321542746017363 0ustar www-datawww-datarequire 'tins/hash_union' module Tins class ::Hash if method_defined?(:|) warn "#{self}#| already defined, didn't include at #{__FILE__}:#{__LINE__}" else include HashUnion end end end tins-1.1.0/lib/tins/xt/date_time_dummy.rb0000644000004100000410000000014312321542746020373 0ustar www-datawww-datarequire 'tins/date_time_dummy' module Tins class ::DateTime include DateTimeDummy end end tins-1.1.0/lib/tins/xt/annotate.rb0000644000004100000410000000010312321542746017032 0ustar www-datawww-datarequire 'tins/annotate' class Module include Tins::Annotate end tins-1.1.0/lib/tins/xt/concern.rb0000644000004100000410000000051212321542746016654 0ustar www-datawww-datarequire 'tins/concern' module Tins module Concern module ModuleMixin def [](*args) Thread.current[:tin_concern_args] = args self end def tins_concern_args Thread.current[:tin_concern_args] end end end class ::Module include Tins::Concern::ModuleMixin end end tins-1.1.0/lib/tins/xt/uniq_by.rb0000644000004100000410000000027112321542746016675 0ustar www-datawww-datarequire 'tins/uniq_by' module Tins module ::Enumerable include UniqBy end class ::Array include UniqBy def uniq_by!(&b) replace uniq_by(&b) end end end tins-1.1.0/lib/tins/xt/full.rb0000644000004100000410000000177412321542746016202 0ustar www-datawww-datarequire 'tins/xt/blank' module Tins module Full # Returns the object if it isn't blank (as in Object#blank?), otherwise it # returns nil. If a block was given as an argument and the object isn't # blank, the block is executed with the object as its first argument. If an # argument +dispatch+ was given and the object wasn't blank the method # given by dispatch is called on the object. This is the same as # foo.full?(&:bar) in the previous block form. def full?(dispatch = nil, *args) if blank? obj = nil #elsif Module === dispatch # TODO # dispatch.found?(self) elsif dispatch obj = __send__(dispatch, *args) obj = nil if obj.blank? else obj = self end if block_given? and obj yield obj else obj end end def all_full? if respond_to?(:all?) && all?(&:full?) block_given? ? yield(self) : self end end end class ::Object include Full end end tins-1.1.0/lib/tins/xt/ask_and_send.rb0000644000004100000410000000014112321542746017634 0ustar www-datawww-datarequire 'tins/ask_and_send' module Tins class ::Object include Tins::AskAndSend end end tins-1.1.0/lib/tins/xt/string_underscore.rb0000644000004100000410000000014712321542746020770 0ustar www-datawww-datamodule Tins require 'tins/string_underscore' class ::String include StringUnderscore end end tins-1.1.0/lib/tins/xt/named.rb0000644000004100000410000000172312321542746016316 0ustar www-datawww-datarequire 'tins/xt/string_version' class Object if RUBY_VERSION.version >= '1.9'.version def named(name, method, *args, &named_block) extend Module.new { define_method(name) do |*rest, &block| block = named_block if named_block __send__(method, *(args + rest), &block) end } end else def named(name, method, *args, &block) extend Module.new { define_method(name) { |*rest| __send__(method, *(args + rest), &block) } } end end end class Module if RUBY_VERSION.version >= '1.9'.version def named(name, method, *args, &named_block) include Module.new { define_method(name) do |*rest, &block| block = named_block if named_block __send__(method, *(args + rest), &block) end } end else def named(name, method, *args, &block) include Module.new { define_method(name) { |*rest| __send__(method, *(args + rest), &block) } } end end end tins-1.1.0/lib/tins/xt/method_description.rb0000644000004100000410000000054112321542746021112 0ustar www-datawww-datarequire 'tins/method_description' module Tins class ::UnboundMethod include MethodDescription alias to_s description def inspect "#<#{self.class}: #{description}>" end end class ::Method include MethodDescription alias to_s description def inspect "#<#{self.class}: #{description}>" end end end tins-1.1.0/lib/tins/xt/secure_write.rb0000644000004100000410000000022612321542746017727 0ustar www-datawww-datarequire 'tins/secure_write' module Tins #class ::Object # include Tins::SecureWrite #end class ::IO extend Tins::SecureWrite end end tins-1.1.0/lib/tins/xt/deep_dup.rb0000644000004100000410000000013212321542746017010 0ustar www-datawww-datarequire 'tins/deep_dup' module Tins class ::Object include Tins::DeepDup end end tins-1.1.0/lib/tins/xt/shuffle.rb0000644000004100000410000000033612321542746016665 0ustar www-datawww-datarequire 'tins/shuffle' module Tins class ::Array if method_defined?(:shuffle) warn "#{self}#shuffle already defined, didn't include at #{__FILE__}:#{__LINE__}" else include Shuffle end end end tins-1.1.0/lib/tins/xt/hash_symbolize_keys_recursive.rb0000644000004100000410000000017212321542746023371 0ustar www-datawww-datarequire 'tins/hash_symbolize_keys_recursive' module Tins class ::Hash include HashSymbolizeKeysRecursive end end tins-1.1.0/lib/tins/xt/dslkit.rb0000644000004100000410000000075712321542746016532 0ustar www-datawww-datarequire 'tins' module Tins class ::Module include Tins::Constant include Tins::DSLAccessor include Tins::ClassMethod include Tins::Delegate include Tins::ParameterizedModule include Tins::FromModule end class ::Object include Tins::ThreadLocal include Tins::ThreadGlobal include Tins::InstanceExec include Tins::Interpreter include Tins::Deflect include Tins::ThreadLocal include Tins::Eigenclass include Tins::BlockSelf end end tins-1.1.0/lib/tins/xt/time_dummy.rb0000644000004100000410000000012612321542746017377 0ustar www-datawww-datarequire 'tins/time_dummy' module Tins class ::Time include TimeDummy end end tins-1.1.0/lib/tins/xt/subhash.rb0000644000004100000410000000023512321542746016664 0ustar www-datawww-datarequire 'tins/subhash' module Tins class ::Hash include Tins::Subhash def subhash!(*patterns) replace subhash(*patterns) end end end tins-1.1.0/lib/tins/xt/date_dummy.rb0000644000004100000410000000012612321542746017356 0ustar www-datawww-datarequire 'tins/date_dummy' module Tins class ::Date include DateDummy end end tins-1.1.0/lib/tins/xt/if_predicate.rb0000644000004100000410000000014212321542746017642 0ustar www-datawww-datarequire 'tins/if_predicate' module Tins class ::Object include Tins::IfPredicate end end tins-1.1.0/lib/tins/xt/deep_const_get.rb0000644000004100000410000000013712321542746020212 0ustar www-datawww-datarequire 'tins/deep_const_get' module Tins class ::Object include DeepConstGet end end tins-1.1.0/lib/tins/xt/irb.rb0000644000004100000410000000065412321542746016010 0ustar www-datawww-datarequire 'irb' module Tins IRB = ::IRB module ::IRB def self.examine(binding = TOPLEVEL_BINDING) setup nil workspace = WorkSpace.new binding irb = Irb.new workspace @CONF[:MAIN_CONTEXT] = irb.context catch(:IRB_EXIT) { irb.eval_input } rescue Interrupt exit end end class ::Object def examine(binding = TOPLEVEL_BINDING) IRB.examine(binding) end end end tins-1.1.0/lib/tins/xt/responding.rb0000644000004100000410000000013712321542746017400 0ustar www-datawww-datarequire 'tins/responding' module Tins class ::Object include Tins::Responding end end tins-1.1.0/lib/tins/xt/sexy_singleton.rb0000644000004100000410000000007012321542746020276 0ustar www-datawww-datamodule Tins ::SexySingleton = Tins::SexySingleton end tins-1.1.0/lib/tins/xt/rotate.rb0000644000004100000410000000015512321542746016526 0ustar www-datawww-datamodule Tins class ::Array unless method_defined?(:rotate) include Tins::Rotate end end end tins-1.1.0/lib/tins/xt/require_maybe.rb0000644000004100000410000000014412321542746020057 0ustar www-datawww-datarequire 'tins/require_maybe' module Tins class ::Object include Tins::RequireMaybe end end tins-1.1.0/lib/tins/xt/write.rb0000644000004100000410000000020312321542746016354 0ustar www-datawww-datarequire 'tins/write' module Tins #class ::Object # include Tins::Write #end class ::IO extend Tins::Write end end tins-1.1.0/lib/tins/xt/extract_last_argument_options.rb0000644000004100000410000000017312321542746023402 0ustar www-datawww-datarequire 'tins/extract_last_argument_options' module Tins class ::Array include ExtractLastArgumentOptions end end tins-1.1.0/lib/tins/xt/null.rb0000644000004100000410000000016212321542746016200 0ustar www-datawww-datarequire 'tins/null' module Tins ::NULL = Tins::NULL class ::Object include Tins::Null::Kernel end end tins-1.1.0/lib/tins/xt/count_by.rb0000644000004100000410000000020412321542746017045 0ustar www-datawww-datarequire 'tins/count_by' module Tins module ::Enumerable include CountBy end class ::Array include CountBy end end tins-1.1.0/lib/tins/xt/attempt.rb0000644000004100000410000000013112321542746016700 0ustar www-datawww-datarequire 'tins/attempt' module Tins class ::Object include Tins::Attempt end end tins-1.1.0/lib/tins/xt/symbol_to_proc.rb0000644000004100000410000000020012321542746020251 0ustar www-datawww-datamodule Tins unless ::Symbol.method_defined?(:to_proc) # :nocov: class ::Symbol include ToProc end end end tins-1.1.0/lib/tins/xt/round.rb0000644000004100000410000000023212321542746016353 0ustar www-datawww-datarequire 'tins/round' module Tins module Round class ::Float include Round end class ::Integer include Round end end end tins-1.1.0/lib/tins/to.rb0000644000004100000410000000023412321542746015215 0ustar www-datawww-datamodule Tins module To def to(string) shift_width = (string[/\A\s*/]).size string.gsub(/^[^\S\n]{0,#{shift_width}}/, '') end end end tins-1.1.0/lib/tins/go.rb0000644000004100000410000000317312321542746015205 0ustar www-datawww-datamodule Tins module GO module EnumerableExtension def push(argument) @arguments ||= [] @arguments.push argument self end def each(&block) @arguments.each(&block) self end include Enumerable end module_function # Parses the argument array _args_, according to the pattern _s_, to # retrieve the single character command line options from it. If _s_ is # 'xy:' an option '-x' without an option argument is searched, and an # option '-y foo' with an option argument ('foo'). # # An option hash is returned with all found options set to true or the # found option argument. def go(s, args = ARGV) b, v = s.scan(/(.)(:?)/).inject([ {}, {} ]) { |t, (o, a)| a = a == ':' t[a ? 1 : 0][o] = a ? nil : false t } while a = args.shift a !~ /\A-(.+)/ and args.unshift a and break p = $1 until p == '' o = p.slice!(0, 1) if v.key?(o) if p == '' then a = args.shift or break 1 else a = p end if v[o].nil? a = a.dup a.extend EnumerableExtension a.push a v[o] = a else v[o].push a end break elsif b.key?(o) if b[o] == false b[o]= 1 else b[o] += 1 end else args.unshift a break 1 end end and break end b.merge(v) end end end require 'tins/alias' tins-1.1.0/lib/tins/named_set.rb0000644000004100000410000000022712321542746016534 0ustar www-datawww-datarequire 'set' module Tins class NamedSet < Set def initialize(name) @name = name super() end attr_accessor :name end end tins-1.1.0/lib/tins/string_byte_order_mark.rb0000644000004100000410000000131212321542746021327 0ustar www-datawww-datarequire 'tins/concern' module Tins module StringByteOrderMark def bom_encoding prefix = self[0, 4].force_encoding(Encoding::ASCII_8BIT) case prefix when /\A\xef\xbb\xbf/n then Encoding::UTF_8 when /\A\x00\x00\xff\xfe/n then Encoding::UTF_32BE when /\A\xff\xfe\x00\x00/n then Encoding::UTF_32LE when /\A\xfe\xff/n then Encoding::UTF_16BE when /\A\xff\xfe/n then Encoding::UTF_16LE when /\A\x2b\x2f\x76[\x38-\x39\x2b\x2f]/n then Encoding::UTF_7 when /\A\x84\x31\x95\x33/n then Encoding::GB18030 end end end end require 'tins/alias' tins-1.1.0/lib/tins/string_version.rb0000644000004100000410000000341212321542746017647 0ustar www-datawww-datarequire 'tins/xt/symbol_to_proc' module Tins module StringVersion class Version include Comparable def initialize(string) string =~ /\A[\.\d]+\z/ or raise ArgumentError, "#{string.inspect} isn't a version number" @version = string.frozen? ? string.dup : string end def major self[0] end def major=(number) self[0] = number end def minor self[1] end def minor=(number) self[1] = number end def build self[2] end def build=(number) self[2] = number end def revision self[3] end def revision=(number) self[3] = number end def [](index) array[index] end def []=(index, value) value = value.to_i value >= 0 or raise ArgumentError, "version numbers can't contain negative numbers like #{value}" a = array @array = nil a[index] = value a.map! { |x| x.nil? ? 0 : x } @version.replace a * '.' end def succ! self[-1] += 1 end def pred! self[-1] -= 1 end def <=>(other) pairs = array.zip(other.array) pairs.map! { |a, b| [ a.nil? ? 0 : a, b.nil? ? 0 : b ] } a, b = pairs.transpose a <=> b end def ==(other) (self <=> other).zero? end def array @version.split('.').map(&:to_i) end alias to_a array def to_s @version end alias inspect to_s def version self end end def version if frozen? Version.new(self) else @version ||= Version.new(self) end end end end require 'tins/alias' tins-1.1.0/lib/tins/range_plus.rb0000644000004100000410000000016012321542746016730 0ustar www-datawww-datamodule Tins module RangePlus def +(other) to_a + other.to_a end end end require 'tins/alias' tins-1.1.0/lib/tins/terminal.rb0000644000004100000410000000122012321542746016402 0ustar www-datawww-datarequire 'tins/xt/ask_and_send' begin require 'io/console' rescue LoadError end module Tins module Terminal module_function def rows IO.ask_and_send(:console).ask_and_send(:winsize).ask_and_send(:[], 0) || `stty size 2>/dev/null`.split[0].to_i.nonzero? || `tput lines 2>/dev/null`.to_i.nonzero? || 25 end def lines rows end def columns IO.ask_and_send(:console).ask_and_send(:winsize).ask_and_send(:[], 1) || `stty size 2>/dev/null`.split[1].to_i.nonzero? || `tput cols 2>/dev/null`.to_i.nonzero? || 80 end def cols columns end end end tins-1.1.0/lib/tins/string_camelize.rb0000644000004100000410000000054112321542746017753 0ustar www-datawww-datamodule Tins module StringCamelize def camelize(first_letter = :upper) case first_letter when :upper, true gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } when :lower, false self[0].chr.downcase + camelize[1..-1] end end alias camelcase camelize end end require 'tins/alias' tins-1.1.0/lib/tins/hash_union.rb0000644000004100000410000000041112321542746016723 0ustar www-datawww-datamodule Tins module HashUnion def |(other) case when other.respond_to?(:to_hash) other = other.to_hash when other.respond_to?(:to_h) other = other.to_h end other.merge(self) end end end require 'tins/alias' tins-1.1.0/lib/tins/date_time_dummy.rb0000644000004100000410000000155312321542746017746 0ustar www-datawww-datarequire 'date' module Tins module DateTimeDummy def self.included(modul) class << modul alias really_now now remove_method :now rescue nil def dummy=(value) if value.respond_to?(:to_str) value = DateTime.parse(value.to_str) end @dummy = value end def dummy(value = nil) if value.nil? @dummy else begin old_dummy = @dummy self.dummy = value yield ensure self.dummy = old_dummy end end end def now if dummy dummy.dup elsif caller.first =~ /`now`/ really_now else really_now end end end super end end end require 'tins/alias' tins-1.1.0/lib/tins/annotate.rb0000644000004100000410000000200412321542746016401 0ustar www-datawww-datamodule Tins::Annotate def annotate(name) class << self; self; end.class_eval do define_method(name) do |annotation| instance_variable_set "@__annotation_#{name}__", annotation end define_method("#{name}_of") do |method_name| __send__("#{name}_annotations")[method_name] end define_method("#{name}_annotations") do if instance_variable_defined?("@__annotation_#{name}_annotations__") instance_variable_get "@__annotation_#{name}_annotations__" else instance_variable_set "@__annotation_#{name}_annotations__", {} end end old_method_added = instance_method(:method_added) define_method(:method_added) do |method_name| old_method_added.bind(self).call method_name if annotation = instance_variable_get("@__annotation_#{name}__") __send__("#{name}_annotations")[method_name] = annotation end instance_variable_set "@__annotation_#{name}__", nil end end end end tins-1.1.0/lib/tins/concern.rb0000644000004100000410000000144412321542746016226 0ustar www-datawww-datamodule Tins module Concern def self.extended(base) base.instance_variable_set("@_dependencies", []) end def append_features(base) if base.instance_variable_defined?("@_dependencies") base.instance_variable_get("@_dependencies") << self false else return false if base < self @_dependencies.each { |dep| base.send(:include, dep) } super base.extend const_get("ClassMethods") if const_defined?("ClassMethods") base.class_eval(&@_included_block) if instance_variable_defined?("@_included_block") Thread.current[:tin_concern_args] = nil true end end def included(base = nil, &block) if base.nil? @_included_block = block else super end end end end tins-1.1.0/lib/tins/uniq_by.rb0000644000004100000410000000025112321542746016240 0ustar www-datawww-datamodule Tins module UniqBy def uniq_by(&b) b ||= lambda { |x| x } inject({}) { |h, e| h[b[e]] ||= e; h }.values end end end require 'tins/alias' tins-1.1.0/lib/tins/ask_and_send.rb0000644000004100000410000000052612321542746017210 0ustar www-datawww-datamodule Tins module AskAndSend def ask_and_send(method_name, *args, &block) if respond_to?(method_name) __send__(method_name, *args, &block) end end def ask_and_send!(method_name, *args, &block) if respond_to?(method_name, true) __send__(method_name, *args, &block) end end end end tins-1.1.0/lib/tins/string_underscore.rb0000644000004100000410000000044512321542746020336 0ustar www-datawww-datamodule Tins module StringUnderscore def underscore word = dup word.gsub!(/::/, '/') word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2') word.gsub!(/([a-z\d])([A-Z])/,'\1_\2') word.tr!("-", "_") word.downcase! word end end end require 'tins/alias' tins-1.1.0/lib/tins/version.rb0000644000004100000410000000040712321542746016262 0ustar www-datawww-datamodule Tins # Tins version VERSION = '1.1.0' VERSION_ARRAY = VERSION.split('.').map(&:to_i) # :nodoc: VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc: VERSION_MINOR = VERSION_ARRAY[1] # :nodoc: VERSION_BUILD = VERSION_ARRAY[2] # :nodoc: end tins-1.1.0/lib/tins/method_description.rb0000644000004100000410000000153212321542746020460 0ustar www-datawww-datamodule Tins module MethodDescription def description result = '' if owner <= Module result << receiver.to_s << '.' else result << owner.name.to_s << '#' end result << name.to_s << '(' if respond_to?(:parameters) generated_name = 'x0' result << parameters.map { |p_type, p_name| p_name ||= generated_name.succ! case p_type when :block "&#{p_name}" when :rest "*#{p_name}" when :keyrest "**#{p_name}" when :req p_name when :opt "#{p_name}=" when :key "#{p_name}:" else [ p_name, p_type ] * ':' end } * ',' else result << arity.to_s end result << ')' end end end tins-1.1.0/lib/tins/secure_write.rb0000644000004100000410000000124412321542746017275 0ustar www-datawww-datamodule Tins module SecureWrite # Write to a file atomically def secure_write(filename, content = nil, mode = 'w') temp = File.new(filename + ".tmp.#$$.#{Time.now.to_f}", mode) if content.nil? and block_given? yield temp elsif !content.nil? temp.write content else raise ArgumentError, "either content or block argument required" end temp.fsync size = temp.stat.size temp.close File.rename temp.path, filename size ensure if temp !temp.closed? and temp.close File.file?(temp.path) and File.unlink temp.path end end end end require 'tins/alias' tins-1.1.0/lib/tins/thread_local.rb0000644000004100000410000000256612321542746017226 0ustar www-datawww-datamodule Tins module ThreadLocal @@mutex = Mutex.new @@cleanup = lambda do |my_object_id| my_id = "__thread_local_#{my_object_id}__" @@mutex.synchronize do for t in Thread.list t[my_id] = nil if t[my_id] end end end # Define a thread local variable named _name_ in this module/class. If the # value _value_ is given, it is used to initialize the variable. def thread_local(name, default_value = nil) is_a?(Module) or raise TypeError, "receiver has to be a Module" name = name.to_s my_id = "__thread_local_#{__id__}__" ObjectSpace.define_finalizer(self, @@cleanup) define_method(name) do Thread.current[my_id] ||= {} Thread.current[my_id][name] end define_method("#{name}=") do |value| Thread.current[my_id] ||= {} Thread.current[my_id][name] = value end if default_value Thread.current[my_id] = {} Thread.current[my_id][name] = default_value end self end # Define a thread local variable for the current instance with name _name_. # If the value _value_ is given, it is used to initialize the variable. def instance_thread_local(name, value = nil) sc = class << self extend Tins::ThreadLocal self end sc.thread_local name, value self end end end tins-1.1.0/lib/tins/deep_dup.rb0000644000004100000410000000024412321542746016361 0ustar www-datawww-datamodule Tins module DeepDup def deep_dup Marshal.load(Marshal.dump(self)) rescue TypeError return self end end end require 'tins/alias' tins-1.1.0/lib/tins/shuffle.rb0000644000004100000410000000041412321542746016227 0ustar www-datawww-datamodule Tins module Shuffle # :nocov: def shuffle! (size - 1) .downto(1) do |i| j = rand(i + 1) self[i], self[j] = self[j], self[i] end self end def shuffle dup.shuffle! end end end require 'tins/alias' tins-1.1.0/lib/tins/hash_symbolize_keys_recursive.rb0000644000004100000410000000114412321542746022736 0ustar www-datawww-datamodule Tins module HashSymbolizeKeysRecursive def symbolize_keys_recursive inject(self.class.new) do |h,(k, v)| k = k.to_s k.empty? and next case v when Hash h[k.to_sym] = v.symbolize_keys_recursive when Array h[k.to_sym] = a = v.dup v.each_with_index do |x, i| Hash === x and a[i] = x.symbolize_keys_recursive end else h[k.to_sym] = v end h end end def symbolize_keys_recursive! replace symbolize_keys_recursive end end end require 'tins/alias' tins-1.1.0/lib/tins/dslkit.rb0000644000004100000410000004560212321542746016075 0ustar www-datawww-datarequire 'tins' require 'thread' require 'sync' require 'tins/thread_local' module Tins # This module contains some handy methods to deal with eigenclasses. Those # are also known as virtual classes, singleton classes, metaclasses, plus all # the other names Matz doesn't like enough to actually accept one of the # names. # # The module can be included into other modules/classes to make the methods available. module Eigenclass if Object.respond_to?(:singleton_class) alias eigenclass singleton_class else # Returns the eigenclass of this object. def eigenclass class << self; self; end end end # Evaluates the _block_ in context of the eigenclass of this object. def eigenclass_eval(&block) eigenclass.instance_eval(&block) end end module ClassMethod include Eigenclass # Define a class method named _name_ using _block_. To be able to take # blocks as arguments in the given _block_ Ruby 1.9 is required. def class_define_method(name, &block) eigenclass_eval { define_method(name, &block) } end # Define reader and writer attribute methods for all *ids. def class_attr_accessor(*ids) eigenclass_eval { attr_accessor(*ids) } end # Define reader attribute methods for all *ids. def class_attr_reader(*ids) eigenclass_eval { attr_reader(*ids) } end # Define writer attribute methods for all *ids. def class_attr_writer(*ids) eigenclass_eval { attr_writer(*ids) } end # I boycott attr! end module ThreadGlobal # Define a thread global variable named _name_ in this module/class. If the # value _value_ is given, it is used to initialize the variable. def thread_global(name, default_value = nil) is_a?(Module) or raise TypeError, "receiver has to be a Module" name = name.to_s var_name = "@__#{name}_#{__id__.abs}__" lock = Mutex.new modul = self define_method(name) do lock.synchronize { modul.instance_variable_get var_name } end define_method(name + "=") do |value| lock.synchronize { modul.instance_variable_set var_name, value } end modul.instance_variable_set var_name, default_value if default_value self end # Define a thread global variable for the current instance with name # _name_. If the value _value_ is given, it is used to initialize the # variable. def instance_thread_global(name, value = nil) sc = class << self extend Tins::ThreadGlobal self end sc.thread_global name, value self end end module InstanceExec unless (Object.instance_method(:instance_exec) rescue nil) class << self attr_accessor :pool attr_accessor :count end self.count = 0 self.pool = [] # This is a pure ruby implementation of Ruby 1.9's instance_exec method. It # executes _block_ in the context of this object while parsing *args into # the block. def instance_exec(*args, &block) instance = self id = instance_exec_fetch_symbol InstanceExec.module_eval do begin define_method id, block instance.__send__ id, *args ensure remove_method id if method_defined?(id) end end ensure InstanceExec.pool << id end private @@mutex = Mutex.new # Fetch a symbol from a pool in thread save way. If no more symbols are # available create a new one, that will be pushed into the pool later. def instance_exec_fetch_symbol @@mutex.synchronize do if InstanceExec.pool.empty? InstanceExec.count += 1 symbol = :"__instance_exec_#{InstanceExec.count}__" else symbol = InstanceExec.pool.shift end return symbol end end end end module Interpreter include InstanceExec # Interpret the string _source_ as a body of a block, while passing # *args into the block. # # A small example explains how the method is supposed to be used and how # the *args can be fetched: # # class A # include Tins::Interpreter # def c # 3 # end # end # # A.new.interpret('|a,b| a + b + c', 1, 2) # => 6 # # To use a specified binding see #interpret_with_binding. def interpret(source, *args) interpret_with_binding(source, binding, *args) end # Interpret the string _source_ as a body of a block, while passing # *args into the block and using _my_binding_ for evaluation. # # A small example: # # class A # include Tins::Interpreter # def c # 3 # end # def foo # b = 2 # interpret_with_binding('|a| a + b + c', binding, 1) # => 6 # end # end # A.new.foo # => 6 # # See also #interpret. def interpret_with_binding(source, my_binding, *args) path = '(interpret)' if source.respond_to? :to_io path = source.path if source.respond_to? :path source = source.to_io.read end block = lambda { |*a| eval("lambda { #{source} }", my_binding, path).call(*a) } instance_exec(*args, &block) end end # This module contains the _constant_ method. For small example of its usage # see the documentation of the DSLAccessor module. module Constant # Create a constant named _name_, that refers to value _value_. _value is # frozen, if this is possible. If you want to modify/exchange a value use # DSLAccessor#dsl_reader/DSLAccessor#dsl_accessor instead. def constant(name, value = name) value = value.freeze rescue value define_method(name) { value } end end # The DSLAccessor module contains some methods, that can be used to make # simple accessors for a DSL. # # # class CoffeeMaker # extend Tins::Constant # # constant :on # constant :off # # extend Tins::DSLAccessor # # dsl_accessor(:state) { off } # Note: the off constant from above is used # # dsl_accessor :allowed_states, :on, :off # # def process # allowed_states.include?(state) or fail "Explode!!!" # if state == on # puts "Make coffee." # else # puts "Idle..." # end # end # end # # cm = CoffeeMaker.new # cm.instance_eval do # state # => :off # state on # state # => :on # process # => outputs "Make coffee." # end # # Note that Tins::SymbolMaker is an alternative for Tins::Constant in # this example. On the other hand SymbolMaker can make debugging more # difficult. module DSLAccessor # This method creates a dsl accessor named _name_. If nothing else is given # as argument it defaults to nil. If *default is given as a single # value it is used as a default value, if more than one value is given the # _default_ array is used as the default value. If no default value but a # block _block_ is given as an argument, the block is executed everytime # the accessor is read in the context of the current instance. # # After setting up the accessor, the set or default value can be retrieved # by calling the method +name+. To set a value one can call name # :foo to set the attribute value to :foo or # name(:foo, :bar) to set it to [ :foo, :bar ]. def dsl_accessor(name, *default, &block) variable = "@#{name}" define_method(name) do |*args| if args.empty? result = instance_variable_get(variable) if result.nil? result = if default.empty? block && instance_eval(&block) elsif default.size == 1 default.first else default end instance_variable_set(variable, result) result else result end else instance_variable_set(variable, args.size == 1 ? args.first : args) end end end # This method creates a dsl reader accessor, that behaves exactly like a # #dsl_accessor but can only be read not set. def dsl_reader(name, *default, &block) variable = "@#{name}" define_method(name) do |*args| if args.empty? result = instance_variable_get(variable) if result.nil? if default.empty? block && instance_eval(&block) elsif default.size == 1 default.first else default end else result end else raise ArgumentError, "wrong number of arguments (#{args.size} for 0)" end end end end # This module can be included in another module/class. It generates a symbol # for every missing method that was called in the context of this # module/class. module SymbolMaker # Returns a symbol (_id_) for every missing method named _id_. def method_missing(id, *args) if args.empty? id else super end end end # This module can be used to extend another module/class. It generates # symbols for every missing constant under the namespace of this # module/class. module ConstantMaker # Returns a symbol (_id_) for every missing constant named _id_. def const_missing(id) id end end module BlankSlate # Creates an anonymous blank slate class, that only responds to the methods # *ids. ids can be Symbols, Strings, and Regexps that have to match # the method name with #===. def self.with(*ids) opts = Hash === ids.last ? ids.pop : {} ids = ids.map { |id| Regexp === id ? id : id.to_s } klass = opts[:superclass] ? Class.new(opts[:superclass]) : Class.new klass.instance_eval do instance_methods.each do |m| m = m.to_s undef_method m unless m =~ /^(__|object_id)/ or ids.any? { |i| i === m } end end klass end end # See examples/recipe.rb and examples/recipe2.rb how this works at the # moment. module Deflect # The basic Deflect exception class DeflectError < StandardError; end class << self extend Tins::ThreadLocal # A thread local variable, that holds a DeflectorCollection instance for # the current thread. thread_local :deflecting end # A deflector is called with a _class_, a method _id_, and its # *args. class Deflector < Proc; end # This class implements a collection of deflectors, to make them available # by emulating Ruby's message dispatch. class DeflectorCollection def initialize @classes = {} end # Add a new deflector _deflector_ for class _klass_ and method name _id_, # and return self. # def add(klass, id, deflector) k = @classes[klass] k = @classes[klass] = {} unless k k[id.to_s] = deflector self end # Return true if messages are deflected for class _klass_ and method name # _id_, otherwise return false. def member?(klass, id) !!(k = @classes[klass] and k.key?(id.to_s)) end # Delete the deflecotor class _klass_ and method name _id_. Returns the # deflector if any was found, otherwise returns true. def delete(klass, id) if k = @classes[klass] d = k.delete id.to_s @classes.delete klass if k.empty? d end end # Try to find a deflector for class _klass_ and method _id_ and return # it. If none was found, return nil instead. def find(klass, id) klass.ancestors.find do |k| if d = @classes[k] and d = d[id.to_s] return d end end end end @@sync = Sync.new # Start deflecting method calls named _id_ to the _from_ class using the # Deflector instance deflector. def deflect_start(from, id, deflector) @@sync.synchronize do Deflect.deflecting ||= DeflectorCollection.new Deflect.deflecting.member?(from, id) and raise DeflectError, "#{from}##{id} is already deflected" Deflect.deflecting.add(from, id, deflector) from.class_eval do define_method(id) do |*args| if Deflect.deflecting and d = Deflect.deflecting.find(self.class, id) d.call(self, id, *args) else super(*args) end end end end end # Return true if method _id_ is deflected from class _from_, otherwise # return false. def self.deflect?(from, id) Deflect.deflecting && Deflect.deflecting.member?(from, id) end # Return true if method _id_ is deflected from class _from_, otherwise # return false. def deflect?(from, id) Deflect.deflect?(from, id) end # Start deflecting method calls named _id_ to the _from_ class using the # Deflector instance deflector. After that yield to the given block and # stop deflecting again. def deflect(from, id, deflector) @@sync.synchronize do begin deflect_start(from, id, deflector) yield ensure deflect_stop(from, id) end end end # Stop deflection method calls named _id_ to class _from_. def deflect_stop(from, id) @@sync.synchronize do Deflect.deflecting.delete(from, id) or raise DeflectError, "#{from}##{id} is not deflected from" from.instance_eval { remove_method id } end end end # This module can be included into modules/classes to make the delegate # method available. module Delegate # A method to easily delegate methods to an object, stored in an # instance variable or returned by a method call. # # It's used like this: # class A # delegate :method_here, :@obj, :method_there # end # or: # class A # delegate :method_here, :method_call, :method_there # end # # _other_method_name_ defaults to method_name, if it wasn't given. def delegate(method_name, obj, other_method_name = method_name) raise ArgumentError, "obj wasn't defined" unless obj =begin 1.9 only: define_method(method_name) do |*args, &block| instance_variable_get(obj).__send__(other_method_name, *args, &block) end =end obj = obj.to_s if obj[0] == ?@ class_eval <<-EOS def #{method_name}(*args, &block) instance_variable_get('#{obj}').__send__( '#{other_method_name}', *args, &block) end EOS else class_eval <<-EOS def #{method_name}(*args, &block) __send__('#{obj}').__send__( '#{other_method_name}', *args, &block) end EOS end end end # This module includes the block_self module_function. module BlockSelf module_function # This method returns the receiver _self_ of the context in which _block_ # was created. def block_self(&block) eval 'self', block.__send__(:binding) end end # This module contains a configurable method missing delegator and can be # mixed into a module/class. module MethodMissingDelegator # Including this module in your classes makes an _initialize_ method # available, whose first argument is used as method_missing_delegator # attribute. If a superior _initialize_ method was defined it is called # with all arguments but the first. module DelegatorModule include Tins::MethodMissingDelegator def initialize(delegator, *a, &b) self.method_missing_delegator = delegator super(*a, &b) if defined? super end end # This class includes DelegatorModule and can be used as a superclass # instead of including DelegatorModule. class DelegatorClass include DelegatorModule end # This object will be the receiver of all missing method calls, if it has a # value other than nil. attr_accessor :method_missing_delegator # Delegates all missing method calls to _method_missing_delegator_ if this # attribute has been set. Otherwise it will call super. def method_missing(id, *a, &b) unless method_missing_delegator.nil? method_missing_delegator.__send__(id, *a, &b) else super end end end module ParameterizedModule # Pass _args_ and _block_ to configure the module and then return it after # calling the parameterize method has been called with these arguments. The # _parameterize_ method should return a configured module. def parameterize_for(*args, &block) respond_to?(:parameterize) ? parameterize(*args, &block) : self end end module FromModule include ParameterizedModule alias from parameterize_for def parameterize(opts = {}) modul = opts[:module] or raise ArgumentError, 'option :module is required' import_methods = Array(opts[:methods]) result = modul.dup remove_methods = modul.instance_methods.map(&:to_sym) - import_methods.map(&:to_sym) remove_methods.each do |m| begin result.__send__ :remove_method, m rescue NameError end end result end end module Scope def scope_push(scope_frame, name = :default) scope_get(name).push scope_frame self end def scope_pop(name = :default) scope_get(name).pop scope_get(name).empty? and Thread.current[name] = nil self end def scope_top(name = :default) scope_get(name).last end def scope_reverse(name = :default, &block) scope_get(name).reverse_each(&block) end def scope_block(scope_frame, name = :default) scope_push(scope_frame, name) yield self ensure scope_pop(name) end def scope_get(name = :default) Thread.current[name] ||= [] end def scope(name = :default) scope_get(name).dup end end module DynamicScope class Context < Hash def [](name) super name.to_sym end def []=(name, value) super name.to_sym, value end end include Scope attr_accessor :dynamic_scope_name def dynamic_defined?(id) self.dynamic_scope_name ||= :variables scope_reverse(dynamic_scope_name) { |c| c.key?(id) and return true } false end def dynamic_scope(&block) self.dynamic_scope_name ||= :variables scope_block(Context.new, dynamic_scope_name, &block) end def method_missing(id, *args) self.dynamic_scope_name ||= :variables if args.empty? and scope_reverse(dynamic_scope_name) { |c| c.key?(id) and return c[id] } super elsif args.size == 1 and id.to_s =~ /(.*?)=\Z/ c = scope_top(dynamic_scope_name) or super c[$1] = args.first else super end end end end DSLKit = Tins tins-1.1.0/lib/tins/time_dummy.rb0000644000004100000410000000173112321542746016747 0ustar www-datawww-datarequire 'time' module Tins module TimeDummy def self.included(modul) class << modul alias really_new new alias really_now now remove_method :now rescue nil remove_method :new rescue nil def dummy=(value) if value.respond_to?(:to_str) value = Time.parse(value.to_str) end @dummy = value end def dummy(value = nil) if value.nil? @dummy else begin old_dummy = @dummy self.dummy = value yield ensure self.dummy = old_dummy end end end def new(*a) if dummy dummy.dup elsif caller.first =~ /`now`/ really_now else really_new(*a) end end def now new end end super end end end require 'tins/alias' tins-1.1.0/lib/tins/time_freezer.rb0000644000004100000410000000043012321542746017251 0ustar www-datawww-datarequire 'tins/xt/time_dummy' require 'tins/xt/date_time_dummy' require 'tins/xt/date_dummy' module Tins::TimeFreezer def self.freeze(time) Time.dummy(time) do DateTime.dummy(time) do Date.dummy(time) do yield end end end end end tins-1.1.0/lib/tins/subhash.rb0000644000004100000410000000241312321542746016231 0ustar www-datawww-datamodule Tins module Subhash # Create a subhash from this hash, that only contains key-value pairs # matching +patterns+ and return it. +patterns+ can be for example /^foo/ # to put 'foobar' and 'foobaz' or 'foo'/:foo to put 'foo' into the subhash. # # If a block is given this method yields to it after the first pattern # matched with a 3-tuple of +(key, value, match_data)+ using the return # value of the block as the value of the result hash. +match_data+ is a # MatchData instance if the matching pattern was a regular rexpression # otherwise it is nil. def subhash(*patterns) patterns.map! do |pat| pat = pat.to_sym.to_s if pat.respond_to?(:to_sym) pat.respond_to?(:match) ? pat : pat.to_s end result = if default_proc self.class.new(&default_proc) else self.class.new(default) end if block_given? each do |k, v| patterns.each { |pat| if pat === k.to_s result[k] = yield(k, v, $~) break end } end else each do |k, v| result[k] = v if patterns.any? { |pat| pat === k.to_s } end end result end end end require 'tins/alias' tins-1.1.0/lib/tins/date_dummy.rb0000644000004100000410000000156512321542746016733 0ustar www-datawww-datarequire 'date' module Tins module DateDummy def self.included(modul) class << modul alias really_today today remove_method :today rescue nil def dummy=(value) if value.respond_to?(:to_str) value = Date.parse(value.to_str) end @dummy = value end def dummy(value = nil) if value.nil? @dummy else begin old_dummy = @dummy self.dummy = value yield ensure self.dummy = old_dummy end end end def today if dummy dummy.dup elsif caller.first =~ /`today`/ really_today else really_today end end end super end end end require 'tins/alias' tins-1.1.0/lib/tins/memoize.rb0000644000004100000410000000513112321542746016241 0ustar www-datawww-datarequire 'tins/extract_last_argument_options' module Tins module Memoize module CacheMethods # Return the cache object. def __memoize_cache__ @__memoize_cache__ ||= {} end # Clear cached values for all methods/functions. def memoize_cache_clear __memoize_cache__.clear self end end class ::Module # Automatically memoize calls of the the methods +method_ids+. The # memoized results do NOT ONLY depend on the arguments, but ALSO on the # object the method is called on. def memoize_method(*method_ids) method_ids.extend(ExtractLastArgumentOptions) method_ids, opts = method_ids.extract_last_argument_options include CacheMethods method_ids.each do |method_id| method_id = method_id.to_s.to_sym orig_method = instance_method(method_id) __send__(:define_method, method_id) do |*args| mc = __memoize_cache__ if mc.key?(method_id) and result = mc[method_id][args] result else (mc[method_id] ||= {})[args] = result = orig_method.bind(self).call(*args) $DEBUG and warn "#{self.class} cached method #{method_id}(#{args.inspect unless args.empty?}) = #{result.inspect} [#{__id__}]" opts[:freeze] and result.freeze end result end end method_ids.size == 1 ? method_ids.first : method_ids end include CacheMethods # Automatically memoize calls of the functions +function_ids+. The # memoized result does ONLY depend on the arguments given to the # function. def memoize_function(*function_ids) function_ids.extend(ExtractLastArgumentOptions) function_ids, opts = function_ids.extract_last_argument_options mc = __memoize_cache__ function_ids.each do |function_id| function_id = function_id.to_s.to_sym orig_function = instance_method(function_id) __send__(:define_method, function_id) do |*args| if mc.key?(function_id) and result = mc[function_id][args] result else (mc[function_id] ||= {})[args] = result = orig_function.bind(self).call(*args) opts[:freeze] and result.freeze $DEBUG and warn "#{self.class} cached function #{function_id}(#{args.inspect unless args.empty?}) = #{result.inspect}" end result end end function_ids.size == 1 ? function_ids.first : function_ids end end end end require 'tins/alias' tins-1.1.0/lib/tins/if_predicate.rb0000644000004100000410000000012712321542746017212 0ustar www-datawww-datamodule Tins module IfPredicate def if? self ? self : nil end end end tins-1.1.0/lib/tins/deep_const_get.rb0000644000004100000410000000201112321542746017550 0ustar www-datawww-datamodule Tins module DeepConstGet if ::Object.method(:const_defined?).arity == 1 # :nocov: # We do not create coverage on 1.8 def self.const_defined_in?(modul, constant) modul.const_defined?(constant) end # :nocov: else def self.const_defined_in?(modul, constant) modul.const_defined?(constant, false) end end def deep_const_get(path, start_module = Object) path.to_s.split('::').inject(start_module) do |p, c| case when c.empty? if start_module == Object Object else raise ArgumentError, "top level constants cannot be reached from"\ " start module #{start_module.inspect}" end when ::Tins::DeepConstGet.const_defined_in?(p, c) then p.const_get(c) else begin p.const_missing(c) rescue NameError => e raise ArgumentError, "can't get const #{path}: #{e}" end end end end end end tins-1.1.0/lib/tins/alias.rb0000644000004100000410000000001512321542746015661 0ustar www-datawww-dataSpruz = Tins tins-1.1.0/lib/tins/responding.rb0000644000004100000410000000061312321542746016744 0ustar www-datawww-datamodule Tins module Responding def responding?(*method_names) Class.new do define_method(:to_s) do "Responding to #{method_names * ', '}" end alias inspect to_s define_method(:===) do |object| method_names.all? do |method_name| object.respond_to?(method_name) end end end.new end end end tins-1.1.0/lib/tins/lines_file.rb0000644000004100000410000000473612321542746016717 0ustar www-datawww-datamodule Tins class LinesFile module LineExtension attr_reader :line_number def filename lines_file.filename.dup end end def self.for_filename(filename, line_number = nil) obj = new(File.readlines(filename), line_number) obj.filename = filename obj end def self.for_file(file, line_number = nil) obj = new(file.readlines, line_number) obj.filename = file.path obj end def self.for_lines(lines, line_number = nil) new(lines, line_number) end def initialize(lines, line_number = nil) @lines = lines @lines.each_with_index do |line, i| line.extend LineExtension line.instance_variable_set :@line_number, i + 1 line.instance_variable_set :@lines_file, self end instance_variable_set :@line_number, line_number || (@lines.empty? ? 0 : 1) end attr_accessor :filename attr_reader :line_number def rewind self.line_number = 1 self end def next! old = line_number self.line_number += 1 line_number > old ? self : nil end def previous! old = line_number self.line_number -= 1 line_number < old ? self : nil end def line_number=(number) number = number.to_i if number > 0 && number <= last_line_number @line_number = number end end def last_line_number @lines.size end def empty? @lines.empty? end def each(&block) empty? and return self old_line_number = line_number 1.upto(last_line_number) do |number| self.line_number = number block.call(line) end self ensure self.line_number = old_line_number end include Enumerable def line index = line_number - 1 @lines[index] if index >= 0 end def file_linenumber "#{filename}:#{line_number}" end def match_backward(regexp, previous_after_match = false) begin if line =~ regexp previous_after_match and previous! return $~.captures end end while previous! end def match_forward(regexp, next_after_match = false) begin if line =~ regexp next_after_match and next! return $~.captures end end while next! end def to_s "#{line_number} #{line.chomp}" end def inspect "#<#{self.class}: #{to_s.inspect}>" end end end require 'tins/alias' tins-1.1.0/lib/tins/sexy_singleton.rb0000644000004100000410000000152512321542746017651 0ustar www-datawww-datarequire 'singleton' module Tins SexySingleton = Singleton.dup module SexySingleton module SingletonClassMethods end end class << SexySingleton alias __old_singleton_included__ included def included(klass) __old_singleton_included__(klass) (class << klass; self; end).class_eval do if Object.method_defined?(:respond_to_missing?) def respond_to_missing?(name, *args) instance.respond_to?(name) || super end else def respond_to?(name, *args) instance.respond_to?(name) || super end end def method_missing(name, *args, &block) if instance.respond_to?(name) instance.__send__(name, *args, &block) else super end end end super end end end tins-1.1.0/lib/tins/rotate.rb0000644000004100000410000000035512321542746016075 0ustar www-datawww-datamodule Tins module Rotate def rotate!(n = 1) if n >= 0 n.times { push shift } else (-n).times { unshift pop } end self end def rotate(n = 1) clone.rotate!(n) end end end tins-1.1.0/lib/tins/require_maybe.rb0000644000004100000410000000024212321542746017423 0ustar www-datawww-datamodule Tins module RequireMaybe def require_maybe(library) require library rescue LoadError => e block_given? and yield e end end end tins-1.1.0/lib/tins/write.rb0000644000004100000410000000071412321542746015730 0ustar www-datawww-datarequire 'tins/secure_write' module Tins module Write def self.extended(modul) modul.extend SecureWrite if modul.respond_to?(:write) $DEBUG and warn "Skipping inclusion of Tins::Write#write method, include Tins::Write::SecureWrite#secure_write instead" else class << modul; self; end.instance_eval do alias_method :write, :secure_write end end super end end end require 'tins/alias' tins-1.1.0/lib/tins/extract_last_argument_options.rb0000644000004100000410000000047312321542746022752 0ustar www-datawww-datamodule Tins module ExtractLastArgumentOptions def extract_last_argument_options last_argument = last if last_argument.respond_to?(:to_hash) and options = last_argument.to_hash.dup then return self[0..-2], options else return dup, {} end end end end tins-1.1.0/lib/tins/module_group.rb0000644000004100000410000000032412321542746017274 0ustar www-datawww-datamodule Tins module ModuleGroup def self.[](*modules) modul = Module.new modules.each do |m| m.module_eval { include modul } end modul end end end require 'tins/alias' tins-1.1.0/lib/tins/token.rb0000644000004100000410000000157512321542746015724 0ustar www-datawww-datamodule Tins class Token < String DEFAULT_ALPHABET = ((?0..?9).to_a + (?a..?z).to_a + (?A..?Z).to_a).freeze #def initialize(bits: 128, length: nil, alphabet: DEFAULT_ALPHABET) def initialize(options = {}) bits = options[:bits] || 128 length = options[:length] alphabet = options[:alphabet] || DEFAULT_ALPHABET alphabet.size > 1 or raise ArgumentError, 'need at least 2 symbols in alphabet' if length length > 0 or raise ArgumentError, 'length has to be positive' else bits > 0 or raise ArgumentError, 'bits has to be positive' length = (Math.log(1 << bits) / Math.log(alphabet.size)).ceil end self.bits = (Math.log(alphabet.size ** length) / Math.log(2)).floor token = '' length.times { token << alphabet[rand(alphabet.size)] } super token end attr_accessor :bits end end tins-1.1.0/lib/tins/xt.rb0000644000004100000410000000233112321542746015226 0ustar www-datawww-datarequire 'tins' module Tins require 'tins/xt/attempt' require 'tins/xt/blank' require 'tins/xt/count_by' require 'tins/xt/deep_dup' require 'tins/xt/file_binary' require 'tins/xt/full' require 'tins/xt/hash_symbolize_keys_recursive' require 'tins/xt/hash_union' require 'tins/xt/irb' require 'tins/xt/named' require 'tins/xt/null' require 'tins/xt/p' require 'tins/xt/partial_application' require 'tins/xt/range_plus' require 'tins/xt/require_maybe' require 'tins/xt/round' require 'tins/xt/secure_write' require 'tins/xt/string' require 'tins/xt/subhash' require 'tins/xt/symbol_to_proc' require 'tins/xt/time_dummy' require 'tins/xt/date_dummy' require 'tins/xt/date_time_dummy' require 'tins/xt/uniq_by' require 'tins/xt/write' require 'tins/xt/if_predicate' require 'tins/xt/ask_and_send' require 'tins/xt/extract_last_argument_options' require 'tins/xt/deep_const_get' require 'tins/xt/responding' require 'tins/xt/proc_compose' require 'tins/xt/proc_prelude' require 'tins/xt/rotate' require 'tins/xt/to' require 'tins/xt/sexy_singleton' require 'tins/xt/method_description' require 'tins/xt/annotate' require 'tins/xt/concern' require 'tins/xt/dslkit' end tins-1.1.0/lib/tins/once.rb0000644000004100000410000000105712321542746015523 0ustar www-datawww-datamodule Tins module Once include File::Constants module_function def only_once(lock_filename = nil, locking_constant = nil) lock_filename ||= $0 locking_constant ||= LOCK_EX f = File.new(lock_filename, RDONLY) f.flock(locking_constant) and yield ensure if f f.flock LOCK_UN f.close end end def try_only_once(lock_filename = nil, locking_constant = nil, &block) only_once(lock_filename, locking_constant || LOCK_EX | LOCK_NB, &block) end end end require 'tins/alias' tins-1.1.0/lib/tins/null.rb0000644000004100000410000000250612321542746015551 0ustar www-datawww-datamodule Tins # Implementation of the null object pattern in Ruby. module Null def method_missing(*) self end def const_missing(*) self end def to_s '' end def to_str nil end def to_f 0.0 end def to_i 0 end def to_int nil end def to_a [] end def to_ary nil end def inspect 'NULL' end def nil? true end def blank? true end def as_json(*) end def to_json(*) 'null' end module Kernel def null(value = nil) value.nil? ? Tins::NULL : value end alias Null null def null_plus(opts = {}) value = opts[:value] opts[:caller] = caller if respond_to?(:caller_locations, true) opts[:caller_locations] = caller_locations end value.nil? ? Tins::NullPlus.new(opts) : value end alias NullPlus null_plus end end class NullClass < Module include Tins::Null end NULL = NullClass.new.freeze class NullPlus include Tins::Null def initialize(opts = {}) class << self; self; end.class_eval do opts.each do |name, value| define_method(name) { value } end end end end end require 'tins/alias' tins-1.1.0/lib/tins/limited.rb0000644000004100000410000000152612321542746016227 0ustar www-datawww-datarequire 'thread' module Tins class Limited # Create a Limited instance, that runs _maximum_ threads at most. def initialize(maximum) @mutex = Mutex.new @continue = ConditionVariable.new @maximum = Integer(maximum) raise ArgumentError, "maximum < 1" if @maximum < 1 @count = 0 end # The maximum number of worker threads. attr_reader :maximum # Execute _maximum_ number of threads in parallel. def execute @mutex.synchronize do loop do if @count < @maximum @count += 1 Thread.new do yield @mutex.synchronize { @count -= 1 } @continue.signal end return else @continue.wait(@mutex) end end end end end end require 'tins/alias' tins-1.1.0/lib/tins/generator.rb0000644000004100000410000000375412321542746016573 0ustar www-datawww-datamodule Tins # This class can create generator objects, that can produce all tuples, that # would be created by as many for-loops as dimensions were given. # # The generator # g = Tins::Generator[1..2, %w[a b c]] # produces # g.to_a # => [[1, "a"], [1, "b"], [1, "c"], [2, "a"], [2, "b"], [2, "c"]] # # The 'each' method can be used to iterate over the tuples # g.each { |a, b| puts "#{a} #{b}" } # and Tins::Generator includes the Enumerable module, so # Enumerable.instance_methods can be used as well: # g.select { |a, b| %w[a c].include? b } # => [[1, "a"], [1, "c"], [2, "a"], [2, "c"]] # class Generator include Enumerable # Create a new Generator object from the enumberables _enums_. def self.[](*enums) new(enums) end # Create a new Generator instance. Use the objects in the Array _enums_ # as dimensions. The should all respond to the :each method (see module # Enumerable in the core ruby library). def initialize(enums) @enums, @iterators, @n = [], [], 0 enums.each { |e| add_dimension(e) } end # Iterate over all tuples produced by this generator and yield to them. def each(&block) # :yield: tuple recurse(&block) self end def recurse(tuple = [ nil ] * @n, i = 0, &block) if i < @n - 1 then @enums[i].__send__(@iterators[i]) do |x| tuple[i] = x recurse(tuple, i + 1, &block) end else @enums[i].__send__(@iterators[i]) do |x| tuple[i] = x yield tuple.dup end end end private :recurse # Add another dimension to this generator. _enum_ is an object, that ought # to respond to the _iterator_ method (defaults to :each). def add_dimension(enum, iterator = :each) @enums << enum @iterators << iterator @n += 1 end # Return the size of this generator, that is the number of its dimensions. def size @enums.size end end end require 'tins/alias' tins-1.1.0/lib/tins/bijection.rb0000644000004100000410000000174312321542746016547 0ustar www-datawww-datamodule Tins class Bijection < Hash def self.[](*pairs) pairs.size % 2 == 0 or raise ArgumentError, "odd number of arguments for #{self}" new.fill do |obj| (pairs.size / 2).times do |i| j = 2 * i key = pairs[j] value = pairs[j + 1] obj.key?(key) and raise ArgumentError, "duplicate key #{key.inspect} for #{self}" obj.inverted.key?(value) and raise ArgumentError, "duplicate value #{value.inspect} for #{self}" obj[pairs[j]] = pairs[j + 1] end end end def initialize(inverted = Bijection.new(self)) @inverted = inverted end def fill if empty? yield self freeze end self end def freeze r = super unless @inverted.frozen? @inverted.freeze end r end def []=(key, value) key?(key) and return super @inverted[value] = key end attr_reader :inverted end end tins-1.1.0/lib/tins/count_by.rb0000644000004100000410000000022112321542746016411 0ustar www-datawww-datamodule Tins module CountBy def count_by(&b) b ||= lambda { |x| true } inject(0) { |s, e| s += 1 if b[e]; s } end end end tins-1.1.0/lib/tins/attempt.rb0000644000004100000410000000225212321542746016253 0ustar www-datawww-datamodule Tins module Attempt def attempt(opts = {}, &block) sleep = nil exception_class = StandardError if Numeric === opts attempts = opts else attempts = opts[:attempts] || 1 exception_class = opts[:exception_class] if opts.key?(:exception_class) sleep = opts[:sleep] reraise = opts[:reraise] end return if attempts <= 0 count = 0 if exception_class.nil? begin count += 1 if block.call(count) return true elsif count < attempts sleep_duration(sleep, count) end end until count == attempts false else begin count += 1 block.call(count) true rescue exception_class if count < attempts sleep_duration(sleep, count) retry end reraise ? raise : false end end end private def sleep_duration(duration, count) case duration when Numeric sleep duration when Proc sleep duration.call(count) end end end end tins-1.1.0/lib/tins/round.rb0000644000004100000410000000233312321542746015724 0ustar www-datawww-datamodule Tins # A bit more versatile rounding for Ruby module Round def self.included(klass) if klass.instance_method(:round) klass.class_eval do begin alias_method :__old_round__, :round remove_method :round rescue NameError end end super else raise NoMethodError, 'no round method found' end end def round(places = nil) if places == nil || places == 0 return __old_round__ elsif places.respond_to?(:to_int) places = places.to_int else raise TypeError, "argument places has to be like an Integer" end if places < 0 max_places = -Math.log(self.abs + 1) / Math.log(10) raise ArgumentError, "places has to be >= #{max_places.ceil}" if max_places > places end t = self f = 10.0 ** places t *= f if t.infinite? result = self else if t >= 0.0 t = (t + 0.5).floor elsif t < 0.0 t = (t - 0.5).ceil end t /= f result = t.nan? ? self : t end max_places and result = result.to_i # if places < 0 result end end end require 'tins/alias' tins-1.1.0/lib/tins.rb0000644000004100000410000000273712321542746014605 0ustar www-datawww-datamodule Tins require 'tins/attempt' require 'tins/bijection' require 'tins/count_by' require 'tins/deep_dup' require 'tins/file_binary' require 'tins/find' require 'tins/generator' require 'tins/go' require 'tins/hash_symbolize_keys_recursive' require 'tins/hash_union' require 'tins/limited' require 'tins/lines_file' require 'tins/memoize' require 'tins/minimize' require 'tins/module_group' require 'tins/null' require 'tins/once' require 'tins/p' require 'tins/partial_application' require 'tins/range_plus' require 'tins/require_maybe' require 'tins/round' require 'tins/secure_write' require 'tins/shuffle' require 'tins/string_camelize' require 'tins/string_underscore' require 'tins/string_version' require 'tins/subhash' require 'tins/time_dummy' require 'tins/date_dummy' require 'tins/date_time_dummy' require 'tins/time_freezer' require 'tins/to_proc' require 'tins/uniq_by' require 'tins/version' require 'tins/write' require 'tins/extract_last_argument_options' require 'tins/deep_const_get' require 'tins/responding' require 'tins/proc_compose' require 'tins/proc_prelude' require 'tins/concern' require 'tins/rotate' require 'tins/to' require 'tins/terminal' require 'tins/sexy_singleton' require 'tins/method_description' require 'tins/annotate' require 'tins/token' require 'tins/dslkit' if defined? ::Encoding require 'tins/string_byte_order_mark' end end require 'tins/alias' tins-1.1.0/lib/dslkit.rb0000644000004100000410000000006212321542746015107 0ustar www-datawww-datarequire 'tins/alias' require 'tins/dslkit/polite' tins-1.1.0/lib/dslkit/0000755000004100000410000000000012321542746014564 5ustar www-datawww-datatins-1.1.0/lib/dslkit/polite.rb0000644000004100000410000000002612321542746016403 0ustar www-datawww-datarequire 'tins/dslkit' tins-1.1.0/lib/dslkit/rude.rb0000644000004100000410000000003112321542746016042 0ustar www-datawww-datarequire 'tins/xt/dslkit' tins-1.1.0/metadata.yml0000644000004100000410000002604512321542746015036 0ustar www-datawww-data--- !ruby/object:Gem::Specification name: tins version: !ruby/object:Gem::Version version: 1.1.0 platform: ruby authors: - Florian Frank autorequire: bindir: bin cert_chain: [] date: 2014-04-07 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: gem_hadar requirement: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: 1.0.0 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: 1.0.0 - !ruby/object:Gem::Dependency name: test-unit requirement: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: '2.5' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: '2.5' description: All the stuff that isn't good/big enough for a real library. email: flori@ping.de executables: [] extensions: [] extra_rdoc_files: - README.rdoc - lib/dslkit.rb - lib/dslkit/polite.rb - lib/dslkit/rude.rb - lib/spruz.rb - lib/tins.rb - lib/tins/alias.rb - lib/tins/annotate.rb - lib/tins/ask_and_send.rb - lib/tins/attempt.rb - lib/tins/bijection.rb - lib/tins/concern.rb - lib/tins/count_by.rb - lib/tins/date_dummy.rb - lib/tins/date_time_dummy.rb - lib/tins/deep_const_get.rb - lib/tins/deep_dup.rb - lib/tins/dslkit.rb - lib/tins/extract_last_argument_options.rb - lib/tins/file_binary.rb - lib/tins/find.rb - lib/tins/generator.rb - lib/tins/go.rb - lib/tins/hash_symbolize_keys_recursive.rb - lib/tins/hash_union.rb - lib/tins/if_predicate.rb - lib/tins/limited.rb - lib/tins/lines_file.rb - lib/tins/memoize.rb - lib/tins/method_description.rb - lib/tins/minimize.rb - lib/tins/module_group.rb - lib/tins/named_set.rb - lib/tins/null.rb - lib/tins/once.rb - lib/tins/p.rb - lib/tins/partial_application.rb - lib/tins/proc_compose.rb - lib/tins/proc_prelude.rb - lib/tins/range_plus.rb - lib/tins/require_maybe.rb - lib/tins/responding.rb - lib/tins/rotate.rb - lib/tins/round.rb - lib/tins/secure_write.rb - lib/tins/sexy_singleton.rb - lib/tins/shuffle.rb - lib/tins/string_byte_order_mark.rb - lib/tins/string_camelize.rb - lib/tins/string_underscore.rb - lib/tins/string_version.rb - lib/tins/subhash.rb - lib/tins/terminal.rb - lib/tins/thread_local.rb - lib/tins/time_dummy.rb - lib/tins/time_freezer.rb - lib/tins/to.rb - lib/tins/to_proc.rb - lib/tins/token.rb - lib/tins/uniq_by.rb - lib/tins/version.rb - lib/tins/write.rb - lib/tins/xt.rb - lib/tins/xt/annotate.rb - lib/tins/xt/ask_and_send.rb - lib/tins/xt/attempt.rb - lib/tins/xt/blank.rb - lib/tins/xt/concern.rb - lib/tins/xt/count_by.rb - lib/tins/xt/date_dummy.rb - lib/tins/xt/date_time_dummy.rb - lib/tins/xt/deep_const_get.rb - lib/tins/xt/deep_dup.rb - lib/tins/xt/dslkit.rb - lib/tins/xt/extract_last_argument_options.rb - lib/tins/xt/file_binary.rb - lib/tins/xt/full.rb - lib/tins/xt/hash_symbolize_keys_recursive.rb - lib/tins/xt/hash_union.rb - lib/tins/xt/if_predicate.rb - lib/tins/xt/irb.rb - lib/tins/xt/method_description.rb - lib/tins/xt/named.rb - lib/tins/xt/null.rb - lib/tins/xt/p.rb - lib/tins/xt/partial_application.rb - lib/tins/xt/proc_compose.rb - lib/tins/xt/proc_prelude.rb - lib/tins/xt/range_plus.rb - lib/tins/xt/require_maybe.rb - lib/tins/xt/responding.rb - lib/tins/xt/rotate.rb - lib/tins/xt/round.rb - lib/tins/xt/secure_write.rb - lib/tins/xt/sexy_singleton.rb - lib/tins/xt/shuffle.rb - lib/tins/xt/string.rb - lib/tins/xt/string_byte_order_mark.rb - lib/tins/xt/string_camelize.rb - lib/tins/xt/string_underscore.rb - lib/tins/xt/string_version.rb - lib/tins/xt/subhash.rb - lib/tins/xt/symbol_to_proc.rb - lib/tins/xt/time_dummy.rb - lib/tins/xt/to.rb - lib/tins/xt/uniq_by.rb - lib/tins/xt/write.rb files: - ".gitignore" - ".travis.yml" - COPYING - Gemfile - README.rdoc - Rakefile - TODO - VERSION - examples/add_one.png - examples/add_one.stm - examples/bb3.png - examples/bb3.stm - examples/bb3_19.stm - examples/concatenate_compare.mtm - examples/concatenate_compare.png - examples/concatenate_compare_19.mtm - examples/length_difference.mtm - examples/length_difference.png - examples/length_difference_19.mtm - examples/let.rb - examples/mail.rb - examples/minsky.rb - examples/multiply.reg - examples/null_pattern.rb - examples/ones_difference-mtm.png - examples/ones_difference-stm.png - examples/ones_difference.mtm - examples/ones_difference.stm - examples/ones_difference_19.mtm - examples/ones_difference_19.stm - examples/prefix-equals-suffix-reversed-with-infix.png - examples/prefix-equals-suffix-reversed-with-infix.stm - examples/prefix-equals-suffix-reversed-with-infix_19.stm - examples/recipe.rb - examples/recipe2.rb - examples/recipe_common.rb - examples/subtract.reg - examples/turing-graph.rb - examples/turing.rb - lib/dslkit.rb - lib/dslkit/polite.rb - lib/dslkit/rude.rb - lib/spruz.rb - lib/tins.rb - lib/tins/alias.rb - lib/tins/annotate.rb - lib/tins/ask_and_send.rb - lib/tins/attempt.rb - lib/tins/bijection.rb - lib/tins/concern.rb - lib/tins/count_by.rb - lib/tins/date_dummy.rb - lib/tins/date_time_dummy.rb - lib/tins/deep_const_get.rb - lib/tins/deep_dup.rb - lib/tins/dslkit.rb - lib/tins/extract_last_argument_options.rb - lib/tins/file_binary.rb - lib/tins/find.rb - lib/tins/generator.rb - lib/tins/go.rb - lib/tins/hash_symbolize_keys_recursive.rb - lib/tins/hash_union.rb - lib/tins/if_predicate.rb - lib/tins/limited.rb - lib/tins/lines_file.rb - lib/tins/memoize.rb - lib/tins/method_description.rb - lib/tins/minimize.rb - lib/tins/module_group.rb - lib/tins/named_set.rb - lib/tins/null.rb - lib/tins/once.rb - lib/tins/p.rb - lib/tins/partial_application.rb - lib/tins/proc_compose.rb - lib/tins/proc_prelude.rb - lib/tins/range_plus.rb - lib/tins/require_maybe.rb - lib/tins/responding.rb - lib/tins/rotate.rb - lib/tins/round.rb - lib/tins/secure_write.rb - lib/tins/sexy_singleton.rb - lib/tins/shuffle.rb - lib/tins/string_byte_order_mark.rb - lib/tins/string_camelize.rb - lib/tins/string_underscore.rb - lib/tins/string_version.rb - lib/tins/subhash.rb - lib/tins/terminal.rb - lib/tins/thread_local.rb - lib/tins/time_dummy.rb - lib/tins/time_freezer.rb - lib/tins/to.rb - lib/tins/to_proc.rb - lib/tins/token.rb - lib/tins/uniq_by.rb - lib/tins/version.rb - lib/tins/write.rb - lib/tins/xt.rb - lib/tins/xt/annotate.rb - lib/tins/xt/ask_and_send.rb - lib/tins/xt/attempt.rb - lib/tins/xt/blank.rb - lib/tins/xt/concern.rb - lib/tins/xt/count_by.rb - lib/tins/xt/date_dummy.rb - lib/tins/xt/date_time_dummy.rb - lib/tins/xt/deep_const_get.rb - lib/tins/xt/deep_dup.rb - lib/tins/xt/dslkit.rb - lib/tins/xt/extract_last_argument_options.rb - lib/tins/xt/file_binary.rb - lib/tins/xt/full.rb - lib/tins/xt/hash_symbolize_keys_recursive.rb - lib/tins/xt/hash_union.rb - lib/tins/xt/if_predicate.rb - lib/tins/xt/irb.rb - lib/tins/xt/method_description.rb - lib/tins/xt/named.rb - lib/tins/xt/null.rb - lib/tins/xt/p.rb - lib/tins/xt/partial_application.rb - lib/tins/xt/proc_compose.rb - lib/tins/xt/proc_prelude.rb - lib/tins/xt/range_plus.rb - lib/tins/xt/require_maybe.rb - lib/tins/xt/responding.rb - lib/tins/xt/rotate.rb - lib/tins/xt/round.rb - lib/tins/xt/secure_write.rb - lib/tins/xt/sexy_singleton.rb - lib/tins/xt/shuffle.rb - lib/tins/xt/string.rb - lib/tins/xt/string_byte_order_mark.rb - lib/tins/xt/string_camelize.rb - lib/tins/xt/string_underscore.rb - lib/tins/xt/string_version.rb - lib/tins/xt/subhash.rb - lib/tins/xt/symbol_to_proc.rb - lib/tins/xt/time_dummy.rb - lib/tins/xt/to.rb - lib/tins/xt/uniq_by.rb - lib/tins/xt/write.rb - tests/annotate_test.rb - tests/ask_and_send_test.rb - tests/attempt_test.rb - tests/bijection_test.rb - tests/blank_full_test.rb - tests/concern_test.rb - tests/count_by_test.rb - tests/date_dummy_test.rb - tests/date_time_dummy_test.rb - tests/deep_const_get_test.rb - tests/deep_dup_test.rb - tests/dslkit_test.rb - tests/dynamic_scope_test.rb - tests/extract_last_argument_options_test.rb - tests/file_binary_test.rb - tests/find_test.rb - tests/from_module_test.rb - tests/generator_test.rb - tests/go_test.rb - tests/hash_symbolize_keys_recursive_test.rb - tests/hash_union_test.rb - tests/if_predicate_test.rb - tests/limited_test.rb - tests/lines_file_test.rb - tests/memoize_test.rb - tests/method_description_test.rb - tests/minimize_test.rb - tests/module_group_test.rb - tests/named_set_test.rb - tests/named_test.rb - tests/null_test.rb - tests/p_test.rb - tests/partial_application_test.rb - tests/proc_compose_test.rb - tests/proc_prelude_test.rb - tests/range_plus_test.rb - tests/require_maybe_test.rb - tests/responding_test.rb - tests/rotate_test.rb - tests/round_test.rb - tests/scope_test.rb - tests/secure_write_test.rb - tests/sexy_singleton_test.rb - tests/shuffle_test.rb - tests/string_byte_order_mark_test.rb - tests/string_camelize_test.rb - tests/string_underscore_test.rb - tests/string_version_test.rb - tests/subhash_test.rb - tests/test_helper.rb - tests/time_dummy_test.rb - tests/time_freezer_test.rb - tests/to_test.rb - tests/token_test.rb - tests/uniq_by_test.rb - tins.gemspec homepage: http://flori.github.com/tins licenses: - MIT metadata: {} post_install_message: rdoc_options: - "--title" - Tins - Useful stuff. - "--main" - README.rdoc require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: rubygems_version: 2.2.2 signing_key: specification_version: 4 summary: Useful stuff. test_files: - tests/annotate_test.rb - tests/ask_and_send_test.rb - tests/attempt_test.rb - tests/bijection_test.rb - tests/blank_full_test.rb - tests/concern_test.rb - tests/count_by_test.rb - tests/date_dummy_test.rb - tests/date_time_dummy_test.rb - tests/deep_const_get_test.rb - tests/deep_dup_test.rb - tests/dslkit_test.rb - tests/dynamic_scope_test.rb - tests/extract_last_argument_options_test.rb - tests/file_binary_test.rb - tests/find_test.rb - tests/from_module_test.rb - tests/generator_test.rb - tests/go_test.rb - tests/hash_symbolize_keys_recursive_test.rb - tests/hash_union_test.rb - tests/if_predicate_test.rb - tests/limited_test.rb - tests/lines_file_test.rb - tests/memoize_test.rb - tests/method_description_test.rb - tests/minimize_test.rb - tests/module_group_test.rb - tests/named_set_test.rb - tests/named_test.rb - tests/null_test.rb - tests/p_test.rb - tests/partial_application_test.rb - tests/proc_compose_test.rb - tests/proc_prelude_test.rb - tests/range_plus_test.rb - tests/require_maybe_test.rb - tests/responding_test.rb - tests/rotate_test.rb - tests/round_test.rb - tests/scope_test.rb - tests/secure_write_test.rb - tests/sexy_singleton_test.rb - tests/shuffle_test.rb - tests/string_byte_order_mark_test.rb - tests/string_camelize_test.rb - tests/string_underscore_test.rb - tests/string_version_test.rb - tests/subhash_test.rb - tests/test_helper.rb - tests/time_dummy_test.rb - tests/time_freezer_test.rb - tests/to_test.rb - tests/token_test.rb - tests/uniq_by_test.rb tins-1.1.0/.gitignore0000644000004100000410000000012512321542746014512 0ustar www-datawww-data.*.sw[pon] .AppleDouble .DS_Store .bundle .rbx .rvmrc Gemfile.lock coverage pkg tags tins-1.1.0/VERSION0000644000004100000410000000000612321542746013570 0ustar www-datawww-data1.1.0 tins-1.1.0/TODO0000644000004100000410000000000012321542746013202 0ustar www-datawww-datatins-1.1.0/checksums.yaml.gz0000444000004100000410000000041412321542746016011 0ustar www-datawww-data[WBSe;V0 "R::zN Y /ǤNvgv]^~^?_[bل&@jǎ"q&܁Ke=3zr+95.0&Jَ#"=B9EW+$N