pax_global_header00006660000000000000000000000064137716401140014516gustar00rootroot0000000000000052 comment=d01161fcf7f85f3552196c5e5857a15c1597dfe2 rqrcode-1.2.0/000077500000000000000000000000001377164011400131555ustar00rootroot00000000000000rqrcode-1.2.0/.github/000077500000000000000000000000001377164011400145155ustar00rootroot00000000000000rqrcode-1.2.0/.github/workflows/000077500000000000000000000000001377164011400165525ustar00rootroot00000000000000rqrcode-1.2.0/.github/workflows/ruby.yml000066400000000000000000000012101377164011400202500ustar00rootroot00000000000000name: rqrcode on: push: branches: - master - release/* pull_request: branches: - master jobs: build: name: Test Ruby ${{ matrix.ruby_version }} on ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: matrix: ruby_version: [2.5.x, 2.6.x] os: [ubuntu-latest] steps: - uses: actions/checkout@v1 - name: Use Ruby ${{ matrix.ruby_version }} uses: actions/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby_version }} - name: Gem install and test run: | gem install bundler bundle install --jobs 4 --retry 3 bundle exec rspec rqrcode-1.2.0/.gitignore000066400000000000000000000002231377164011400151420ustar00rootroot00000000000000/.bundle/ /.yardoc /_yardoc/ /coverage/ /doc/ /pkg/ /spec/reports/ /tmp/ /.devcontainer/ .rvmrc *.sublime-project *.sublime-workspace Gemfile.lock rqrcode-1.2.0/.rspec000066400000000000000000000000361377164011400142710ustar00rootroot00000000000000--color --require spec_helper rqrcode-1.2.0/Gemfile000066400000000000000000000001411377164011400144440ustar00rootroot00000000000000source "https://rubygems.org" # Specify your gem's dependencies in rqrcode-base.gemspec gemspec rqrcode-1.2.0/LICENSE.txt000066400000000000000000000020731377164011400150020ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2008 Duncan Robertson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. rqrcode-1.2.0/README.md000066400000000000000000000104541377164011400144400ustar00rootroot00000000000000# RQRCode ![](https://github.com/whomwah/rqrcode/workflows/rqrcode/badge.svg) [RQRCode](https://github.com/whomwah/rqrcode) is a library for creating and rendering QR codes into various formats. It has a simple interface with all the standard QR code options. It was adapted from the Javascript library by Kazuhiko Arase. * QR code is trademarked by Denso Wave inc * Minimum Ruby version is `>= 2.3` * For `rqrcode` releases `< 1.0.0` please use [this README](https://github.com/whomwah/rqrcode/blob/cd2732a68434e6197c219e6c8cbdadfce0c4c4f3/README.md) ## Installing Add this line to your application's `Gemfile`: ```ruby gem 'rqrcode' ``` or install manually: ```ruby gem install rqrcode ``` ## Basic usage example ```ruby require 'rqrcode' qr = RQRCode::QRCode.new('http://github.com') result = '' qr.qrcode.modules.each do |row| row.each do |col| result << (col ? 'X' : 'O') end result << "\n" end puts result ``` ### Advanced Options These are the various QR Code generation options provided by [rqrqcode_core](https://github.com/whomwah/rqrcode_core). ``` string - the string you wish to encode size - the size of the qrcode (default 4) level - the error correction level, can be: * Level :l 7% of code can be restored * Level :m 15% of code can be restored * Level :q 25% of code can be restored * Level :h 30% of code can be restored (default :h) mode - the mode of the qrcode (defaults to alphanumeric or byte_8bit, depending on the input data): * :number * :alphanumeric * :byte_8bit * :kanji ``` Example ``` qrcode = RQRCodeCore::QRCode.new('hello world', size: 1, level: :m, mode: :alphanumeric) ``` ## Render types You can output your QR code in various forms. These are detailed below: ### as SVG The SVG renderer will produce a stand-alone SVG as a `String` ```ruby require 'rqrcode' qrcode = RQRCode::QRCode.new("http://github.com/") # NOTE: showing with default options specified explicitly svg = qrcode.as_svg( offset: 0, color: '000', shape_rendering: 'crispEdges', module_size: 6, standalone: true ) ``` ![QR code with github url](./images/github-qrcode.svg) ### as ANSI The ANSI renderer will produce as a string with ANSI color codes. ```ruby require 'rqrcode' qrcode = RQRCode::QRCode.new("http://github.com/") # NOTE: showing with default options specified explicitly svg = qrcode.as_ansi( light: "\033[47m", dark: "\033[40m", fill_character: ' ', quiet_zone_size: 4 ) ``` ![QR code with github url](./images/ansi-screen-shot.png) ### as PNG The library can produce a PNG. Result will be a `ChunkyPNG::Image` instance. ```ruby require 'rqrcode' qrcode = RQRCode::QRCode.new("http://github.com/") # NOTE: showing with default options specified explicitly png = qrcode.as_png( bit_depth: 1, border_modules: 4, color_mode: ChunkyPNG::COLOR_GRAYSCALE, color: 'black', file: nil, fill: 'white', module_px_size: 6, resize_exactly_to: false, resize_gte_to: false, size: 120 ) IO.binwrite("/tmp/github-qrcode.png", png.to_s) ``` ![QR code with github url](./images/github-qrcode.png) ### On the console ( just because you can ) ```ruby require 'rqrcode' qr = RQRCode::QRCode.new('http://kyan.com', size: 4, level: :h) puts qr.to_s ``` Output: ``` xxxxxxx x x xxx xxxxxxx x x xxxxx x x x x x xxx x x x x x xxx x x xxx x xxx x xxx x xxx x x xxx x xxx x x x x xxx x ... etc ``` ## API Documentation [http://www.rubydoc.info/gems/rqrcode](http://www.rubydoc.info/gems/rqrcode) ## Tests You can run the test suite using: ``` $ ./bin/setup $ bundle exec rspec ``` or try the lib from the console with: ``` $ ./bin/console ``` ## Contributing * Fork the project * Send a pull request * Don't touch the .gemspec, I'll do that when I release a new version ## Authors Original RQRCode author: Duncan Robertson A massive thanks to [all the contributors of the library over the years](https://github.com/whomwah/rqrcode/graphs/contributors). It wouldn't exist if it wasn't for you all. Oh, and thanks to my bosses at https://kyan.com for giving me time to maintain this project. ## Resources * wikipedia:: http://en.wikipedia.org/wiki/QR_Code * Denso-Wave website:: http://www.denso-wave.com/qrcode/index-e.html * kaywa:: http://qrcode.kaywa.com ## Copyright MIT License (http://www.opensource.org/licenses/mit-license.html) rqrcode-1.2.0/_config.yml000066400000000000000000000000311377164011400152760ustar00rootroot00000000000000theme: jekyll-theme-slaterqrcode-1.2.0/bin/000077500000000000000000000000001377164011400137255ustar00rootroot00000000000000rqrcode-1.2.0/bin/console000077500000000000000000000005261377164011400153200ustar00rootroot00000000000000#!/usr/bin/env ruby require "bundler/setup" require "rqrcode" # You can add fixtures and/or initialization code here to make experimenting # with your gem easier. You can also use a different console, if you like. # (If you use this, don't forget to add pry to your Gemfile!) # require "pry" # Pry.start require "irb" IRB.start(__FILE__) rqrcode-1.2.0/bin/setup000077500000000000000000000002031377164011400150060ustar00rootroot00000000000000#!/usr/bin/env bash set -euo pipefail IFS=$'\n\t' set -vx bundle install # Do any other automated setup that you need to do here rqrcode-1.2.0/images/000077500000000000000000000000001377164011400144225ustar00rootroot00000000000000rqrcode-1.2.0/images/ansi-screen-shot.png000066400000000000000000002456161377164011400203300ustar00rootroot00000000000000PNG  IHDR#nsRGB pHYs  YiTXtXML:com.adobe.xmp 1 L'Y@IDATxifY߹<\w.LۦHZ |@: 'XtE 6DB7|IH(Bc_wTsթSg>׻󞪺WW{LYϚ^{biyy֭^Uoy\Oν w4S3SO}iO~ԗiv4p/5\R?T= ձc'c+K׫՛k_--TNSjuz555YmllU3N599YMMOW{^5V511YM>1QW{:}۩ݨ;Քj^^!ȴxmVU⿧ {Ĕ>Z3dUmV'NU+W}4)yvww4vwvU)eSfݝjW<̾hQqD#В"[RZȹX-<:C8DI4`'.J#Qn|R/UP]70UA}wBӔQW/|ԳS8`p]:2 ^#Ri6J H&q8.٘ufY-l7(CK\`$|o9V-!YS6jdo|[տ:~x5 zU3$̔*iz7c'NV kׅ=Q,/Uo(jss]8#}}c#!Б,/T.]jfyںe32kaQOImi_Ʋ rS WǰATa/jw]u23յ՛zB)FaV,la #fW?f\tB%*# tWy0Bva@2ƋVnK}:aQ}ZA 6:F[":oG>M|).++ ɈtbV<ۼ,<cVڋlԠ7aM/D M b]W8VX~aF!gvx#;eq"CMiʛ&Yv/diRR8_.W^ H JkbkJ?a_5MjTn޼U8%Z h4b5}M *oBl գidgOg޽GÚD-jܤ: KcXf.#q`¿y/7y*߸ w*twTuT.bDqfuҥjkSSl҈q!08?Htb4z+WG4$)mi&S"׮y]=mڠ 1N!C٠(kj5: V'^#IUx0MW׮وYaS(XV5e )ViS)&ɟr";#Y-Og72?sA]:rvlG6Ւ<h(=T [ŵʏ аch_R skMu4Y#رig-~^4j0% 1(WrdLll >n3>'e!g gs-fPȦt;jJ\0H:"?:W!{@(Z yBCӑ't<ǁ[CQC50KR6s]ҴӱfmWJ/,U995Wm177XwL5㮙yVsZ/iy٘ A t~6܈ ?#;hf9z]t9OHZ8Ơ2dp9:|"g504-t"[,Ej{t(J ]A!O˷3Q剙H@#4HT:!)aXQڄvϪvɓeƴOp9B;svY`uN\Sծv//-V3?uTlhl$4LA`taJ+ʉဋYHr,`@۠p Lma׸I'6'|[,_Ykmj$46F}ՠcTWݖpݗN|c(~g #z"cƌ r9Qͣ+O ]޸O*a,g?l)t,qp)iZ>@f >8t(Ψp; L/ [” /ӿ~q4 v7t~|S[7Ԑ +J~juv5EuF5;ׯ /nkw+>#a8ðה7NyǁIkO_YG's;k),?WozuIGp4 =A yV>gpo 77 {7u95(SXlx1P;"7{C?hthp=ewZ׏M8f4#;P0%Mt8,ePXGhpG mN(Hm+zэfFfȨ-FĢKGhKb>33[jN878f8{!p Gwq?a*Da"Dxdm4%cv"jw0w؛H=QyG%R*ِꎱóԯu :(ٚkQd}uA913E;͋9rEi|< e+nwtRÄa2$T }3>RddleNtjtr"?uQOՕ'?d&з 9 o-r7z)1I(H:pG ѤEFͼd &hHF"Y:u2aIK:(Gp_sħ4ʲ8n<%}ٕIpMYF-ã` ȕG{Ԗ4&S jJH;!6`ܮN77.Cg̵,oWs8n];+\k: q^&$z@m%2$,C}-eˆT2TnTz spIs8K:K2\nC Fe'\Mxqh~74Kܒ>ě; fHuyƉ]n`7F^C [jpTi>oY2\P*K>H'<>vS=h 3P _;* ;u'#zTS*pd\d8Ң㊄k:gӈx_򻮕7C#i MY0Fc _E4ܐEdCF1A'Rfzl@>x*f-D&J:zF " c=; y9˲Kie=I!.t:;-c5Sƍ _N% (]. Р:i{)Dê<?Bx[a9L9e7,jV[L`0BlxNQr &rɒ|KG G9g#Nr_S-8AhC֬|NÑQbڲ e9Ӹ~MP)?=^j96ڄH>ԇ Uvj٭0m%]e`y .!b:Ӎ>BS4^`h(exW;_ SӺ8 [j(+10ڭ Ȩ,@aNK0poف<,Jtuq%W\*ߘʊyϞ=[-. .w/V}J\,N6f4u-?Zt~إa NRIq~K3?QbvlQ``M|pfOSvzJn0ɨ-N>"l.YJ9R\R/vL(2 kpf ^T\M0 6|KچQȖwd`")j~!W-,Ӊ'.e78FJSr,^Iyѧ범[L#9ՅiP"\I'S[·e)K{0>-AĈ>UJR҂gf(Z4 ]LcTgwrƚ~kǎ-T~]0T冮H `:=RҘ^4< ΀[`7D :~ФgNOсFf|KR2#:$u4p~^ܗ^,[*Ch4u?5*8.Q[Մ!#РLK>h4[ Y#UմJC$!%A:Qǁ9smW˴2}dSƷ^QQGѹWѢ.5BMr˖龦+ˋ5k>@ 5rH)*FMpBU W`˳fVKz!˄m5d{Bcר{L2\_cܸ~Oh4::B<,i62KtEnPPݺ;ϋ嗗/_7xcOykl=(5r~@Jpz18x]<38ϰMV!P^CunjexL#Y G-W _dwOb~[ i]n){-6.^hrIr/^`NNHa M ^5Dq JFvFm5Zˀ= 4^U>yqipx>_ƖcmMmi&zEdpSZ< v.3:5ʋLG't#ߦMوFRpWqA3S3$tOz.aCaL7cCى=3vG(ixLDЉև!W]॰{w˕i|K!StqNHMi1i|0 [BSV S3=o He0axC2,[)G(BKXPFQsIQQW'eAd\yz!`SMo 8ajyg !G(c-AACZqv2,W̸\R+d*> KC V1`pA?ol&{,-u鱳d8#e#%<R膛vt`0(4(hњFtԅO)ECaQj'*JC{TSQƗѹ`iHFM#ﱿﺁS lM+$O逇8hj'}F,7rC2qoަ*N nkvvH~?ڙ?\{f_h({4kX 28D0/t]K>H~83҃N=B=p#Y8V\x( IzwGzH ]ub4ԄN@N>̘]yHKg}NKK! {> )Uz\׾Z[q+7y9vt>!rXѐgv7"e;jBIt &|D18OV׳dvkL#h ~YI8رjjA%;U|%|fIlܴ͊*j]}3`r>Q-;7oV]_я~x}̳{1 mPjcGG}z&.Ge1?_οH+|S? 9'yW 3jP8r=GLN_/տQM $Z^3ϝo(oF׼6>ޱ8]hs ZgW[Q w7f7)f4Y4M~Z{Ƚl~-iJ`?].LbpWҋX<]o$<̂N(VH*.w=̩hγuSԓs窛h.s;Y}ҳzZۜf٬k@:ܻfl!!E]c2|5BKp> %>|zqIg0ĉ?E}+_Jg5qJ)e& .eI ?|y KY_uyկjxlr޿,=Ƴҵ'y՜Y 8)5ٹf7h?Es=X\'vK19sڪͪ]u24K{}Z*zMƬxЉz_u Ϋ-G7M9BːfLS9!m_Qyb4ql!g)89"yK/l?M o}Ѽ[vA.:k+0jx|ԾF&ma\NL8WXQz[4nnqˁU2S36)(nɠ8 ;ikW.;67;阎 r씾_o o)J>W蚫#Ϩpu=/.9bJ͸meTW^3)=^:h@ʍM[ߤ;Npe8,4r> &IR4LN8ptlUlJ65Rn6 7K_<'COp|z]/lX8%;<$s̎H"{Fn_w .yJx+/le^dGkܮ7Ty^R#t{u9΁ Z><٬䘕xRs[_qptpZ7|:yJ2|cH4ځx Z}gx>ׄ+ >k5wfSMUMm):p f9qZGCs86{L=H;=583#8'hQ kaJnɩsnMeWCDBAQ 6ETuE#7GDv]1Q#E.xN8?OWz}t蠸4`T/t+A-/'$e#U$ uxW—FG!vBojg@幧`uyBk^/]̍. #,x-Gc Hԋ Vy>ã$3ZJhBX=m@9]x/KFSڤrǏYO8sS-Fǃ<چN…1è#709#zgFÚ'ڪ4cXEqAg ‹%dXYgf%A҉QVt8̗ WFfסR^s[L ڗ6&mѡ0aR1A$t<[4rLh9D-ϧmx(Kz٦>W.>ܶf:[ la̬~>\'?(8`^ѹbGqB5c?3^Q9 GLv3{ ԓ(p}.: !h.Wb;M \"^`]C?ӱtЮ#<;>84XDc۟ɟeGc:+_h^[>/SOE6uQJ :@_rS.#O;@'I@N:Ft+?4\fG8w8dazZJkOHَeQǵ 2Qh|Q6@ǟxױNe4òuЭf+lA7\ =\V8A EE_i$ș:. %g/B:%шn00 v(n(2mk~١lh|~7I'”Xoow<,g64̏?^Zӧ^CѝҹߍƎe΍ؘɩӤc ,]h9-ZS(-2IoRk/ׁqK?Gt p) za#4̅v/e|3ӼZ^/+._ֲe*R?ufj8(iwjoM/yaYT8{<QE^DzdCdP ;>@KtÖw}a@ơm:wwy 5AK7㸒0wWPi\ ɺvc-^**tĻ _yօ틗˸ntcᄳoK>#QP_ZW!Kze5~)uȬo My1ghTp] ]|.~wt}#^!7l($<~ ;Rt60|~,o2+}K 9JY^s.z4 c%*j8^WtvI뚕iݣy]y%dW'Ϗw`|p0Q8Iu2b_iSGvqS?~W hT?+Q8ZmkGHtEZA Y܉0f͗[c3/Wl/"4Cᇽ0iSdfH޿!iH끝Y6mйV%2gM."q?{\bLAN;ı)7+7V?iU/gwf>qBNi&m޲Ջqx+w6[ښdLׇ7r{i]kD8*-8i0t`K%Ë BXlc'+ "ߪ3XQ< 8i4pF[^řO-_IAJ2c6 cqkЇ>a1>c??m w[o6CЯ,A}8 +^tY3/V+GLOoP%~,@6<0<Ƭk`)G9nfyxiGnЉetYB;阦G۱y<>ӺIi`$WLABf z > XV*'Y18vI95ӓgO>cvJ(e? 7R7H)-|-6`YG:0Տ؏5ǒT>S7c0Lg]'8`dG'cW>U^u(Q~\ںJ=MG{/ޮG>NCTw+Gı,^뿰5%:F.CAn״nD$\DR$<48]Fܹ| ŴOX9F2*; q_2ـJ=f0"v2Z4dO|,is|saJ_u<fkU7Mg{oyLȥ9>J?}k}}ܹQ8.W7'$l;K.xYxʹK\ix:=zsedb!^1HSa7=.8X!>Ft퀤aS6b(ghatNpq:3w9@SYPxMH#ߑ݅ Tï' &Lhqۤv}q8+MkqUD>fȊ1VRHt!G|Ep ԃtoKWqoAu_ֱ|}xy=ԯZ>a#Nf\~|i8xx\( u#\K`8:&/#sBh+`0b&aC6')/2coz^9GRLqtxw!AD= y7.$[ݸrak?+_xneْnbM}SwC68¢a k(g\ &F# N`&t+Ty㢀9U\4vxn_}y*̢V_J5ȃ%7PMÅ G:auDQ] O5_?E zA.X#NIK2\..tM /W?x_օ+ObN`F":uUZt{'YlyUx9efv>>quʥ|#D77hl4+qYv΂ , FQ6Dϛ*xuxK rwPl4BNj~*Kd0\IH>B.ebx)k&qMx: z%,q>U7L+LZtOEwQN1}섂,9M[ !JT v%i')]'%q]T\(\.̷%ݶ.R%*ܼ.XYڍCX5vJ WZ}|\4$Nť7t= ɓ'bt- *ޣV}FzM5\bx`2]}v4'| _6wӽzj(8 ] fK%7nlꩲcq= 5~uu-]zzT'O/.j誣I}U եC8VRܾ̳V~mo̳Tܗ]\ӺEj(U<:C:ʱ҇?ǕVI `90sDd__l7)9FX ZY5 H44QGyh5FkY@BO:pNvF_S a.Pdv Gg$ vU>Ǒ {eIWAKi'cROdwA17< x{D)nL9c %[hϞ*̂FG5t c *uƍ(v^q=+|`&01ìCjbzcJ$n{aj3*)/ fKkxB›noqf=%S:I͐V>SR;蠲Q^Wtsd!!ǍS3oF>͸b^=ғsߔ*-5奜8I 5n Jݷ0 j ZVƻ\yPh?0 bqpA ^JL˝GCS E8zD 8uѼB7FL[ʲ«)WPZ7# |*B 0i]uy-GmÏw66^I;VWתzZUkÊLxF%Ӫޯ+j2,.zz5c\=Ĕ A3hTW#kj \Ef(ƀ1LOhѐN *g{ӲΠBDcaڽ-9NI}RٸRCrMaiED_KQWc5}gxWtϜnUg i]=t|΄;ܘ9p0lgDm3gCoC+qiA)4 XgLhǧ^4d2d`52woSc<|K}ZpN_<:̯~zQ]0^UavoMMզ5Rk4^FIs4^K>=mve|u5/k8Oxq8hPq; ) dHtov)lr(FؔM5fq#W@3DZÛrRvjy>'kUYG([Eg`?9er#<2,G)u ~rM%x RJl.ć8;;!Q)!i 0-wE]zZU@i4S휞J< aiͨy}9uBͦA~>Q(珟¢r!/:TiC8gYÓFtreȤq勨d!U68LGg^03!.[Y) N:Sh ̙42S!blGǾ|/t|+ėS**@e'Ca 2*H2ӘGgIƒ<NA7[UnFFׅ؁GF OHc+F:Q4oh ɟ5yM=#}M y:a$8cr4o4l䐬!']o\hsZ}-B2vNSrlEowJ;FڕLKE6>t_ـ7V&~| h6Bm Sj>ʹ/}0uM*U2-Xd׶h|IfJY|S5QNa$ėźvFLٳM#[d|h◪O~߭~'~z^sugDbR;F`styO=[['N#{2:: 1:_ɆC?CoEQ=p%c~:u&*|6W #-94dBBB MFBc7$B)*g ߚC# A'2u~<)~᠇A<:a\6yFW3za@L0^S@IDAT=qT!z%5%3pI|=e5(<8:Sjooq*5:CX/-`ffW1'+bqyZ%]sqp0);ڷaZhj&^:u lP3wx&](< _IQcuZ,8b:MPg>.駟xFʀi@݄Oo> <W̋ 3JsM(8FFa7 IzM Im.3zl+IsI-Lw$ϸK2B>X#dЍ( C8h>i2B=ј#7 egoQQ;mo՚0^\DlXa(tA3c@ vKZ#@-gvLԲv kWzQ0K,/p%lt48/p,Y7ԁ u8N!5Pe?uf;Ѡw\-lzb/fSS!aKWI&4̆̋?N~X:n?A Fb.h(oA YrL7+9wZA;Lw#-2<_8d.qƕā(W+^: ?VLgy$.[ћ1>5*%օGUI}&8 \=z<.Fĭ`NHΆtۊMI${46G78S4=e>1z7A]y|gb~]b/N'o1^ ,CfL%N$b]>3ZOLݺ syA_5j:il:IkbTAI4vS"rEc L#IW^7,]]?@Ѕ30C꧟,Q9׺JSBw>Ї!' E8ǏGzI)CQ.aңL*xkǢ]kEMJB4Tq ܥNAh t£d;'Hr1//loQA֩[Ŧb@E+L>6 ~8Ns᱌~X׾55lΝ;\VIǑ3 mO_E*xҐ}Ŕg}66-IYip 8"z*NG] I>RLKQ.lB"9u=p4pw2) ]vG]EV<f"8LJ`2eӓ0rѫE=3.\]vsݚ.e(q SOC8%ly2) *u2`dh0\)ʂpʌjB; 9nϪM2?N+OI8% ٌ;ߩ4~v$qS~Kh#n^8(z\0 zw"Z a\RhQ )wXG_t\&zwj:$̹oIs @x\Cֳ#׺Waܬm4(AS5y}KAXw1}#/Ɖ\Q(5oЇhS?l*#k}?pҷ AN`ix@_u'u[LK?ݛync~&"zWI;7ے2n}kcaQrM(~ETcHQ9H1]-`Uǿy,hao+'I "0xm@3M㡢{Hhu v6S |+ xz߆"|9*Q!Q@ zAS`w EF9b2 C?hnЗ{ /h/i@=+ S83ʛ7J?3 ׿(1ٳq"!Rv8@tytsz̙/Tl㮏+QײsH-42 N^(\hZS LRL!}V0vN: !2tCCၷ0rF/~ }IevEG~z[ҜC}sk뺏}cz%'0t:::.? }<_z?VNP.x }q\mCKD%?'!7eKn-<.vI1CIS3&|G/a a0*Fwtl[ xV뙐Qbک5i" q9c:XZ9=8 5<32#Pʚ2yFeݵ(8T-?FFm̆ǗyD ޼QGӥ# |b>pt sz Ӌ 5u|IzaqנGLEY}/ͷ6<^pj;jטb2Gx,Ot6}+IS9Q %,aPDwMiz/_VelϨ4ҕQ~ З0puN%Avy<,~P'N7-7끗JN7-;^f~ %A8e^^V0I2cE%E8Ha9\E4F<:͠S7;n C5(opz~]^EtkqYt?nB/7{'`xC ٮ޼NUt>=c=3BQ8p5 a L;ڰdtJt4GAlL c:\.ݶ؄A&Ϧc,3|÷Cp(/oC6JLaA]y*;O.n8",M0eE.c{`dӷ<0]AM"io?̧֌3ZvNeLjgE2TP0HW4u{X,q_fiϮ~F .&6>M eh`\ u(?78s[R>同Ȇ}c iЦL/R<Þrԇcx9>>oqϼdx>yȳ-R? QepR 1smz.3D_E+?g=+yy C%~,揌ѡKh}|ï^rs/Lc^jCIV.P֗@8y|>QbUUvЫ (zL c7è VaH^(h|?\;w.&218:~'8ZWԀjlG#<ˆo%\}?O1ښXÙ}S[s}׭l@3$}-(GkJGɿ }۹W%L./lM/;u!O'`Hr )BJ \QZ孳\p[>ǓH5OAFhy$1zk3,,*ʚlR䎔tK[8prWf|<s`D1>tu;+XCY;*4| mÙ_GїZ1G\Ō!ߑZFiyLX.nƱd!?eՕWIZYٺ)m R?%2 l$aH?A,KKgtvwy10 ҈[a9Y'ݟC_agJ]iů-6וefYK=w#ˋ.w|]wTNWijp+^/؊W#apˆ b/2jKe%Q9\W"F {3! ni0x6&R|L 0Df|8*>.<5)#87M*Cy,^8>D7ECWi,Hˣ77 ѩU˭N@X{OFq?\-5+A| (i]o9><(!s<ʔ<;d<*IҩK^Wچ.'E\ uX%#=D8N܊ȼ[$8WD4LVenַͩgG>Ro ǐW")Oa3?3Z5ǟ1ڣ~WFk|LGhq1F"OC_4S$KN:Bqi8yg%#e7MqY$?pN*ԣw-g3Qz'>^n_<V^’8atIG3.{EgɆVçh`&`՟fZUYT$Jc3PZY [w*uO/'|c+\C<-O+77ɖg9r1V> 1'MG~ylE 5k$ׅ i3-m[^}lryZMp ?L3}-G#\ ,#n]LYqm:Z}MNLwg:ǣҿWt ]DmL\uŏĵAD ?HF`s`kz>aatOi&(F* o ?;8~0)[(`w'v.褔#\ y]KXV껪.70lJH68MB8H`WRw}.:[Ps0'%G4YͶ1 x9 Cg%GPpYHkwB~ʙ|秌 9`:^wqK8ʅ8߂NSF)aѰ͜Nc|&TC,ef >AV;"(j ~c Ĕ8v =xOg‡%: XW͡'~yt`<޳-A.eLN|r˗P2=HG$Gzî\9*5ʛ5j@c'|pkptlmV:&=Yvh|ʧ ~H?^l OE:l7R>GmBf0|MHJ%Rxy磾-?vB[:xLj:qDlbލkd 1BvaW2@S.vwH/tHruc;,$ ıP6OwEK " <3[-/o_P<2Yy Ͽ4UޢG:p/V촢Cmo[c.3 mo}.K|j6jdPEaT}h)[##yZ~Z/ǮsavZ^f~K8P??;p^O/y]xI!W>̹IZHYo~g>=|y(aD_);8&3ߨ կyM o £GT>irUftRr:B؀G:*i BvX_(eX| BGGCZU]шrLfȧkԴJU/i4[~EoI]=#:X [>;;ӕc5}Z|45>'7oUsSԈ#SUGCJ Îskb8-2Ƙ{,hy+qUL\2QQҍAF X>Gqf§ϑ A-5ޚla8uH!cFB[-Sg| eǘ>2J x(3?= 9#rfy|,6ǜ u ^M|o/qK> wՕ,y+U̶E ;=o95&UME`;AP>5NfOf=ufyQ,qLyF^f OEfJ)qQ0`=r!`bxp@'|+[:܅Y1N2%Чs/K|($Mq0T`l$i>Ğ?X7> 6epqL֕ @'%2 AOa4z N)wew\q=xIm"hꊓTձPgT:5=N☞VX.S}#b~Im\ʤrV0(񨸨viuN};-Vo7-w6/9s=9K:, /1_6S]WKȺvF˼G/:=}xcgM_evϟA إd`tԩƚ8凒ɳ8sY%щB'wa;@ɋ 6qK(S04.jx҉^0D'K5qial*Y.^7o'v˜[]t락&ffb奟S Lc޼zF~dzjFtnM2cG6&vC£2qTM 3gT?s?#+>p^TC<{-=%K (r/n62`8 t|OZ˿ћ]c,#?Ra87"cz|*  :UՎeMz 'Z7ulJ~D!0 _xBV|a|;ܹWIdˑ0BG[:Rh1Y}Íz]kdFX"اpPh@[bj)kK81M3ztH>w6J/"껜5K'zTF.+cv9^4e:Kh &B04M=]V@>CƏ㔸d5T 5!20Ű0<}xemF̻ p‹Z}t%+\$v,ˠl@맴PudMeЃtRyXC*eф ^KapAGQvFVyiPQ^ހCȐӖ `>vHatc:c7KP3Xѡ^-1Y d;yw޻x/E^ΣtľMͯ->ԇ~.-1X891o*qa%E?Ƴ/K4〱]W&2$5Mb}t[b 0Mu ~DSm8H݂9n4qԊ엿2&!anC<ݐߥcnG9~.4[q9GֻE[ 5C7L/"cyGOxB=b)GhyFx8ãGbǜ'ø\.o60sz#ɸ8*L`/iGpg/3e4$8J7 9rv4ݼC]{SwT]Z{h]4tw4gR$)E1~S]]p>vqXtZxsV>dTb=8V CGa*v͵eWrv]6t =8 zK݅>WK*TVtv/id>d9/#ϑo K$B =ZX6;;WbSߩCo{r$MoPƵNa (W|}{bDb2 1z[,^AX=mՋ~~!<VH\]l 8 o}+Ƈ=Ŕʵӡ )?s|Y^@yw76T!/,@t܌ `_yz!&Vrx χհ~P)Plejh8BOA5ǴŕmKcjcgh59T]r kʃﱅ1zӂ xAv΍(?Tm\󞽹y㵯}]̗j_\\>?s}(s- !}g Lpc\I3peڌ|)eO#c!/ȑ C*myzL+ታt|\:cWWkw'S긞HЯH_P3BH%a@2'޼rB(:MA8a8Pc<1U6Alyj{]jl$z)]gv3F=ʊ`[;1&OƮ"lУ/DCXApF&@Ϝ:Y-\dqO9"PfF+仧r5Q_.;hgK-!6a0(fH#FKsZ ;w`5BaAs\Mb4B \ţ6~ps O|WM\]F.^1^5[ |;w.i2JsNo74✖R,p+lDa![X44?'ei*J]j1c XV˝l٣wj $`ǤFi[fIEO^{4?k qYuDI8?8-uGLL7ح' TAgKDr cn?T~PVOClW h,n}[lR#4 /qeʈmYֈ݊j{J{2aSӅ3|yuW\{sMRPCi+:hEՋ^\hzL;BE)33(洰'묢i0]mp@48䅱л/h n`C-4"XGQ,p_vP8qJq 16$o-rѐ7| )G{a*5gfi%pxM2.`;g1WJpO>.^ys Sec˼Cwƕb1(3e,/O}G8>? :U;Dtq T s%2BpŪϙ8 瘝z hj80C%a\yBDkA4gFŽBxc p~N^F5'%u'5;vݙOvFle<-[~ ~@7y@7Ϻ ^[[ǵ\>s뜷/x NJi3-pO2Zs@Cw^NrCW֋ vt)OhGCZO=rNJ|D/Pt60T]PͺsnPIcN 6YױV8½&~;OD~h8rk>/Pt02t?taE/'g|JsZd>b_a+,Ϭ!-ֆ'/(E/)qN 79vR'4W%1G!1 x"./|}U?L50&Oٳ/Ӵgӏ9ER{id\D%.j$P{~vM=Z`#P0zXT*z~~h\g7Bs?7זNCCH̎9 Ex`S^=dL1% +)'Ŝšy͘|ZƓOOMhx2 /V 55!o3xWjnT^eR"kxHC+A`A@9Ȃ^rH_8.5ӛ0#71ګFC{2,% @9*KB8`L54o3Sbx/9 ȟ8[ 1p\Oyy/xJ|~/ %G?V^ Z9逦:̧8o7_9={hN|w2q$5~f{j4$7{j>a: ?9)DKwoqLO]T/ԃ3/c!i008Ji7#(Ѧ[V@c@¥\x}9]# m&;F7)Yji,GQ&A,iMfRk~vܞ8Қ) hC`1 nH8ӪQ5(x١8+R5w}-]`nR^}7ҿGLJ:fY,qLFG!$HĻ@" <?- ׬ `-=p:3k̲믯DCtlṺW sռ0 ``Jƚ|ج\Yu_÷znQapn?O, Í) 3;7F(ss>}¼:#<4vI\6}ϼuw~0@IDAT zX԰HCN/Pt %`Dsnpy~g/hU\[L3|t|zLڈ[Ȗi,98S,{φa^Cљ[ *S!,`b_f1*[z"ꑅQ'|CK ᥐjшQaml>=t2r"a(|飹MX_@tr&! MyK%j+AXO03`{#,iB@޻x}5a|V36,B~./l(V 7b^cݸl.jG53.M IƵ3mttIɰ״ǥ|iBF%F_~UDPBDe-edpPGy.zX,Q"42kNqZ:<_|PSdSCo;^[-F#|:)'|@i Ώrup=4Fs+r -1I8 pFډ'c8$&{# rzAKxXF-W۪<`h,EqK=†^l#}lB}kハJuZaK=jC^!qƋa߂>$$7|42.P#w쵞/iXEr?&1q<%?፧YBtß[ 7*lM<_/K8=W~ez3ln`t^JX?+ q}G5T;%?i ~ҕϼwl!آZB^(96,H pg]ahwQ@ZUVۗטx(Sh<-Y:B圃[8|UGF֓'S BbMá1ĠTZ = [T* UT[VvY}\t$nJ@@_1_oK\oLmG?p1-KR6KP{e_rU{.޳%9waQ>{Mxr )-W9PbpKn=J9+Cvs#V"pf?[os]__ZgVvF!vC ߼H4b642eQs`<@v[ ^FP48BiȜ&nzq>3' }t[g'I`|e4m2LϘ:S.?GnM)NBZ]w>qdo(*q@ 7=G>݀qyMNI\ć^ ` Zm G) eu'x'.B+'2q4!eS  u%?7pFVFr +{+|qǨ1mE<R~NhgjN|˓'[uYD%Mu[pm≢Ni,V@W=qi}~dm($BAI`Ɠy_PC%ɸ=<

2Cx' \?suҡQ%0_jne)WI/]L1FYJvhHT&*|q[}MfB;zr1^nJ01*;w_Jk;245JH\+?q(E7%#2?iMO/~2 1}7az$Cb"?]2A/':pZ2ǭ3 ~B7|ueW]ׁx#7L7}y ?4mpK(Kng;_&nB_2<\E1~dz|Y"3?BZ!i5dax0 ZWaȣw`ބۊ"=ȏ`8 ]Hs~dKs(`xǐ Vx@t9{3y؏.$BzS'2ttW,N׽xICYqi?_IӖyW;CU+L*MHg_CpP~0`f$]<=qq)Xn[-4vq]I{R*U iSaGIN!b-JbLV&^WynvC U=kF2)i- *J[񿈻IEzʹ2[`qY1Dw\a"FJӃxl('$I F V,.f ]v42o,y(rD}BJSx>^B@*dWM$i~)䗼JB" D%?n L|,7Q/+ A#ϔ@n^;4Y/8OFiXy"wn|3WN,{e}|=K6e!|(z7߰AQ7(5Qoz枾.",L'>wC(ZԦ?sjyg sGC@3 ӠJzxC\}tRp︩aK[ ؓ~8Ky 0zyDžveM%{ .qF@a<#;L'Gn@&,p9?Gl@4Ws(imo煼94z}Ef _^F)! axg|oi+]2xw-LvĆh23AdcTWED[MNȨ'ֿ5,e`dc\߰;]KK#3q'zg|oQۯ̐_`׶~SOnSt K0 ]<5Av(p߾+hN2ЍjvC:t",_aɼ ^1*/t\?GE~Ys]NwMk67_+F2 [=R٩B"|)Zۋ-!%ɤːsOCCaH(`wI}%*?eqbX1sWz䙫*;poL*d<xqat 1P沦8]c:'=%ng< BxQ TCtnӣ~lx)JYjd+k~g9J ӔpWÐrNn%fU pVFm.z=T1\ALk TpItR-Lę!\Bى({P0ޗt"L匋0&=WQ-iP :!J'M[3_<}B8*wQ^ep~4 dk. QX Tza ?n3\GU 5_7oV 0ĵ Ym(\]UxjA#5tdE WQVeCx,d3Uq}aߨ>;~Z;NUVU)}W}NRFiP~Ik|׫ :gHq(ըNl}G}c+nr`5=6J } g_q({Eá%iM79y,$4jύFy}o=bT^ A'#^;I:zbz%{B-+$Li(=1mzm| kUk9iwدe& =`'~P H tL!4J[YWջi\sTʧL8YRavMӧ-5`n HQR=d*6Z ;$%B |u躡x. d{Ozvz9¿,Zy&$Yx1ba#^CkIpy}md?LU~|`TvݬKon#F>4ICWy5 4QΦ'5}@'gzgDgH4( a“09|US|p<z:+JWu ^8 M^=sqa yE8aDR !@y5!ف0:b^.ppy;e8t˰|s9_ g].8XzJa!o:7l+PAgzG0x8 2Z@(yo^]j(XP"VKZ+0'^qpظF)@\t s9]& ;j^ nLf$g l.(Fk&U=xe$˕Fty]a|rJl:cvỸa@sapAFp3vr{;y+s/>^C}e0|.SEA9+~ťc#o~4pc;7w8 3t yK:?W2f}|لVsKl1j3GK'FkfDΩT A:wɝ6}4_˹s:v2cUeZ((3c#`1OhJ1JVذɍaLtGnjf|Z n4 LGPF # wZpz[FoN9##YHK!!]<A}D=h^L w!tקގZ a@ϊ3Jy^pc͎Ezk 1^^VB›yeǀU~4El(Q_;7u/ىQE<)ˋle#(QPbFQ6x8t;B_ăev*@ =t^ Kօ >ci} P/1-01oկ~uu%k,ΖdGCXC2 'o5F5#Ճ_0(u y5| ~0QR)ѣSѸwXW[wx1}f<-1SraEf |bȔ n4MkgNׂ?9WNS=OO5"ޣJ:&)ƈ1UQ2QFU'v#Zd(aB| bVy =ʂiXQ~܀cD!.&DJ #W(І;p@Z24ң<{H}ȠLēQԄGp|(ω?sO9vsO܀v|mQpmrdsǣq8l #{dr2u 8wy=vJ9j+rym7+mPIzzlU jmTLP]/Ž/gdRz(7HHQ ',8h8go}p]# Q,0JausP-^QA09d6? { J=p%ڹ.1gfoнҗ; ?,q~s52{úЋe9Kt,NP趩h% q4oiQ4 -έх')+j -ZA}ddtq'զys25ZNʧY|JbdDz3F3q]zg)qG txvZŶ g[67{xs,C 7s=y-A` ni<蝰xvJYc_+cOddžrђ^%V=꯭]D@GϜ99PijpH 1B`p32",t BMF rVFiOaˠe DO=Ӛjft]Kn4$_ڨ.*C9F#2"֭/*0LeVr8^Wp7褴(vmO]ƍw#uT!VrR<ƙN2#ɣ"x!-I=:p,ͧ/|J(Ě,(9c>#'e?-TCa2bO"DJCT ˉ|p?9 4]|g"^0딁J`4x 7?2 vF;݈GYjo_8("-'Cb$;/ua/y*QF4B?qri.^j~߈fк- ꌲA:dC `eG\>"K{nU^kA͎\^24yYJx^SMdi9]I21R(G"%<S#Ih`H>w[ϼpo{|ɿ}퍴`>P]LO8؜gN@PaP󲰳krnIѴhmKBQHX $aۿ۞~V>&hQb1L4QfZo']~0zi|~qbn{S4V >Eۇ]p#|"<7`WgA:q4.ijI4"Ըp:tu_vkܧ1:be$B)6X}m`7xf'*-xQ 9̻MgH"%ejpݾqj06d)諲BK]uHҠb*әB:{*~M=D5 ~T~U}]rD+fep/Rl g.`DNd"\wuaCFRh6xꆪFq\K<>lލ@:qMezL_.М4DZj7e9#ִ|o)"X7{ ?:5 cƲ cykq""1.p( AAL(+B@A80`x]!;8]wA tMZJ\?'I'>s%r^Qq\|H]”{HO{+iQ~(=8LE/w%\$9]ɫ>N䲩;h3OGYƄhGquL6PM)␔fE+8Ɩ=gΫ׷mM.6sNêe͗ZhEɩp-Ȳ>ĚxlB g_3ss Fn3]'oӗЗt ߥ`+Wo_.S_Buw>w_gq;҂$Z }˪(eƐU/g(p 5+дgeeewbֹg%l%atmqҫFb20O=".p4- ޔ_ ýB3J>w?6.p\^}_KW:Aheu)æw;)CmeZ+GL/tWw˲=;sBљcSDE+G"A4fJ^oWnEN@P[JG\409IHMˇ&=B%+Qr#6iIWl`$};p(+Ke!G>R^OðF a}moSnw_XOUp_5=aT97tS׼!7ke{]`8<{>> `XnHvq ,zGI8Q3~z=xwW壂![4JL܏r͞=sx=*tб xy\C89t?g>$y[mYtW^.=WnӤGkeE*a!qϻ%``p^J(ױa[-0,N&Z~-U!1Uɞ9SY, dAk6h!sYswWS$+=]ӡ98(i4?i"nwӛѐt.q-=G9jSU49UrCOtq+PI9iz < t,?@2u|mJR:vJ*:L^uV3k'$.X? )qWV;1lT0d&L-E0?/0Tv!/WӐiq+bcffD(]}*F5/ Ѝt[ S֗hePȻ-c-6@N2uPw#=?.;/w﯄q_ ݅ +fPՍ7\jz*!pL;k~% eF3.錗glH 0/i=pqΫiLa-T˗ O ߽7N~ȃӁwK7ߝ e~wgӃ+% ύJ#C(>4>_ƽe)?+_e"h&`$P&x7n.[om}ѐ4ـJs`h?3M ¡ ?7y |'4~+(gBd8$|ğ \/]:[ [/)/Q]7<ɧV}׋=ǵ8~+[.o;+Y6M ߽'ݕvyml^YATd$({[R2M0@OZ! }ZYrQgqE 5vOWTT5.Fb^&ؖb-a(?yڿwzON)hcŎ i92>=r? n._\sM^sbcGMZp[CyK)h()o``,j C%.([E絢' lHďgϊrG_;>ܔ!2sOS2MyOz4L2~ҸP|~ d k^ȃ?tl2B(D(=)2Zgg浘3&PCG>ğ9dk^.{iL;N:~^Eu-ƈ{W8xo)psHNYE B;FG$}W[pAk<x P~{7ޫõo}[Gz ?#u&kPRpdOEDG1W/-jx :Q{77ECu@#'l\gP V(W -o+g/Z"`"Pt PNUz?C{w:4:2x~nMZ 4AɅ``B0(akePiz+i>#a҄8rRWuդzN8S74IxQD,U!_aFu^##FpX[i}ɓʘ7߆5X Z(C'UEEDKkjey7 gV i{,z:6,+:QƪW@+8*FYXx;QN9i(Nr.qA+8yss{&F+UnBry)x@^aG/ʈiP*9oV޿%o\_y,h:tA %(?rѠP_[K<,=|xȜ\5r"ڭ0mXG?q|C4,:؃jXΑP:.(9_XF+lk7a9mӄf#Q D!°UZǎ1W@ nQ8Ep7BR1a..M}{|kI8 k S`z5wUt!~(<4V^+_pTJ%aJ@' 4봦[x[74#~q^yR(_7C~<n^*3\@IDAT<)}4qpC[.0 𮄋ȈkY3Dr5q:k?Jˁ E;yRDTATjs,[NW ^uUs'~[gwh(WpMF_j8p@+|O{5`;<:^לS1,q IvG.Go3 Wb~r4Tj+7AymJߏ>F H;ComuQx?rZ 6 3le苴4&e%;2}_d\y V%1<2a o} a54aaEѷۮNE-[WmD/aw0~&+]/z􂉡YTZYݺӰk^4 =_N\1Ď6q[c0j =)v(_\S˪6z|zn`ۈ{GFe /. 5JK#Q~:2VSA}]fo4v148:Kyc3Oe86d@;4HCc̹ 5;G*`2~Z$,o|4`q?K8x.o'e۬GN4rSvZޛϙH1s^k]e_N:$y^*AH|4U ¡IxHAv:`^%'JL]G&3mvI9wû b%@ Rn*04!$^QΤEDҢKx}b-g 6xKx,UX1NM$1= X] 9p#F2QGQA84)SDtqxe6)F ;EOR!. *ށ(yПčsT 71J1甾T vo@ ׸<Whr]AHF#0Rr$7=-:x8W(D0/aΑ ҬOmc1L 6ZF4m0_l p1=ryN>(F,w}w^k7rNRqRP{-*^Lf<M5zIŎp'?y1.p!xJ ɇ5?QR#NX )l:k}_ɩ8t ቓo$^:x@jcS4bq-VB0d^^G-`1  ZSn>QUI2!|! ? [pf*-E)$,QPc1R?Olg?;0$80l4P7u1AhP SwVp+3U}ZTJ']ݿ_Kuʹr<;?ܙ4Cj)C'5;h8*|#QWfd[5-U01\mO0 'MzX%]gmeu< s,F㷦-I/MhAs 7bCQrz/`zA%^]cR)y?F%4 u"~,=NAa~Uw06 6FZQ6ޓ4rQvZ d(>'昫ҝ< ’VǟR}m; D̟{/h&zqay+*)5'cE K'}ֽӽhF{ ŐrvMj^ývQ-t^[ U?On[ ́*^d_В.AO5@1 w j,ƒ9i &U3-SZ1I )?_(h{R%P9XHA\(B E=wCB.(9% UFO蕙LO#JxA X,pKRGdhax$֤.pd| T55ЋOHstgS aM3p%S+/cd:U#2<8bTZV A'p6}ӏiL&A-5-^.VW_}u ϸR0 B׽!([ 8vJ9CIpУrlpd'^tRϙsT\W0p"ͲOfج {PuP euQʿo*x':4,{ /.TE-zi) aP"j+:ěFLw$\xu2cAc7eK-97x~LA'h(YQiTQ=S7=L&pvew>)SS3s—AijI͟Ví@#V6T}1R 4bdbyN-#3nOF<1#`7PxX4(##څ}Uu}=wѡSH%ŋe ¨'CYLLpIaOY_EW/{!/$ܛ\Ȼ+7 GL~qLE ׸+qXm GD23 (V%OO C DE!줋8!&jR" a) lw-/]QPBhp&|ߍ7a =L4fHtrxi=@^*,%BPa=Э;+'$M4> Ún~Wx36K:oXJc@e?i J%p|ηl׀q=M.c7~@Wo(OHd3ys"XuP:)0@;:"8d'<[C}xr Nuu>=I$?E-Ѳd 0D4O^1$^d.epQ=3Cхa;/ 7JKeΡŧ- &XF !+80%Ze6V>Kի[@&QP6"eP~ƽ锞*aNVd201*8X<{\sgy6"oZnnK{T} o;z^sNSc}sM44-JzBQW#v}37TJsk{ O<0O4x, I@|dnPzɏtI+~YХM[o )3!~Sާ?a;Kx{kooFC@ȉu腿_L}9 ʴQe2ٍR?ˆ:$HW]uJi='8yB٨"t5 ]RJ֥Yl"CDKx9eCE4;Hb;=?D1Z5 j$AugC _tŸ՞^k,2ZN:F!#{"2>HcEZ D~UgɠW§;%YԴ8 ļ+ȏ.a*G i,Ǟ.8oꉕ縌YOkBL[d4\ }߮:2>hgbRnSƴπk|Xٌm=y44xHCM3 b%iMO<!ll#d ?=dcNmNK|<sY\WrqC^^٦ zԳ?ض([!mPn>4PzBĐH|^ >E`%8FiEPE'bɊ\(#remȽ& 0VAJ+r1 IzUF% ì7B 2Qkg\JufZv,F&⓵c01tzz\#;%Żk@+Nj9 j 4~tj4L.~@Z`KdvcXK42k(H|lb _jb4KLn0QRZV8b(Kc^Ÿ?ƥwD{%objƈSNpaa ~0RVPgF>kV OС .O˂r<8u.y[:xC!'8sm%NdC [$|` ANE{G5Fh`HvGEG/zExsxC?< XF.z1=R &#HϢ-T# | 9 9T7okz%R~#EPF^xBJ]O颡 Id+KXc˗OdEyMG@pyC..L#exʆ{y!IC JF! hJIaC(#-x2) ]wݩEr5Mi=xSOE%R7L*\3 '|=6[x iyE)]њ'"Aܳ%X=OC|{C?=^ħ‚ |,۪#GBI][݃ D!4 m^sNn"g qal Q>~'[D#+!`EqE}q%+(W9ց{Ub2(F঑c_?T>0=0baTAA5wܛv,ڪjXC@΃/dz^B#6ʭ_ ).?{QACw EkHZ R cE;7 oa|v"Eo+!+uspIY1FB7n$!1bmq4`4Ny h*VmqpUoG7̿"0lGc{v]}p_%Ód2FڝT3|OΟ'5 >\!8[8Q%KK:)]1NmY)WAMNw8}:KR(3a306vk3r)Xs>][FݔViIT|P8(˒\d< g.wPey6R;r>|8Nek+P#HVR?WsIW HsO0[DNI%˲VD9ԫ{ [:epVߞ] fvp&2yߖY?lt_6eS T/sf[2A6Sm;WV(s%> \M~|7 - kׇt=}q6{rSᛢp#_h8SE=p;/\K'Q蚩5wc_分=P Gek9Hu[N\ 1$Q/$B sxRn38F B-֤p /3|q5;{Pu|8B`/N'KL >+19 <,+r#WG[|S'rg1:J2? ғ 3F|ZB#eyuVǷY_k?ӺbdWn[giFCwk]?=-YWeu|LSO5Wuk] 0tn?]} n#?%]m9UpmLyLLiy&YۭNug(2"jA427Խqc !+ץH]Jj]Nnw "8{o5op ݣx~^a.OٕUbWk1uT[6[4}\VW0 ?3>O|xwꜲL: ϷySݮDvj=nNX^hh`iULG\J(8q|OWvt OoE՘PkeFf-i>V+<|0|b[m{oigÁ|oE2Pgzq6s4W]_9l}ަס;鷎U<︝v|x}_Z麬5^yߴgs?vO~yw*&9yPlq–^ʂ!5k~[>Xl`:!r"gZix7һ2tYn6q.:Ak3_VQ*}~Liqs$J-wQ $Udԓu,efUFDڏ朁' Ys_׊vt*׎=z@vOߋ#U9`T/A?z[gBlbDzJX6ɧӮF8do].5 4M$p ʍ$zȾ\bt{o!yU|7M +2 SE$Rͽ'Sd،n,&@h3Z/h@}X~sX([T$⹞6|{يȶ-4ҭt$q . R5qԡqB#3O+iR0![m큨l< | =kͲ `!*7fD`]J(4 #zfɄ{6S"FNdiuV4jV9?aצ)^K ްE 8;n"/-0^-{6G{zgFMۅocmy=Sve_ޅlbk炌TsRRл!7QVҒVH3 E;<<ؚ̒SZHciPJm2`[fq  ?Tҁ"ʠ-D׍0CS±eR(q!0uI\k|N1ϷF: '4ѻγ~8ѭʋp)Úyv[g.L)Y#2_ε-o?*Lʜ_fRt#{9apq%hq$c8M&ՀRo{ nNYR4W+tfu@K&"dzKG7$J!+q˶d3kև!+zʵns$VY,fQ֞,ڷ?fƀa݅C7ʏd^g0 {#r'#pdE$C[~#%V$<be]Oc]l{{J@dNTeh=ʤ:AjwkO֊%L)-A-RһJln8FFD# /wg69|_Vm ўV̞??Xݵ](o͏,]da.~K1EċrsrQP7C.-'cBh7:bn{vwѿo8{Wi@3-N1^sNcQ)st o9}Wu"-=zp{bϑ k1h"wgcf7R.*^:h;MűQyf;$k界HO{5ܯWFڂ}B8VrfHΑMNq=9lzL;w 0#A?n}+t1ym8gw2{w3'@1؂Rw'I_z9/8-ff.vu.s r~ u6ØvH)86TyI(I-9J[=)h| eo}yjkg*a] D}֪ h>p~vbt#.S9e6<1ӟB_Hsvܟ#`JdWU?Zi)Z٬4rMLw?Ϙ3/>G-a8[iVh:~f'M13~X;ݪ9G|J{f??zoļ7Kv[0۟j {S0bԹčꮀ.#9gx\ )Ht,bKilGFգcrw=N~&9t9DV~3D?.ZTZn_"H lEęaN<4L"{v~K 0Dc!HYp|ik~3: qԑ}fΧLcJ@Z|\y#6#2Er̆̏Pϕ&p!.7B`Jئ#}|j|t*?z#i֕GoeKC9ZFl]&71klTij `=w[{_+&~(怐é#~[ɵtXx)$PZwwd˜2 Uޤ[:?W'e]fqF"ޡp$Hz8{g8S~e W_+mo5\żgi&Q&]AF(V*at#j!+5u !_1׈߽jgJm& ^^ ȑK)Ǔc[& jmlY?!Gfg_l1:G(Cmf7pOD'z4؇/_"ĝߵ"-=f80;m#/dH=  o邂_L#Ex[hemLVx<یԟg̏VEj0TDH_}?0{|KnԼʼ Sio`^fR8+śo2u"Co3Ms1y-d"}HjYk?WIz L#ZKWxtÄ9 wg~*$d Tƛ;N#f,"[B4Nڡ?v_HFPҭ@IDAT5ẓ1 iQ nF\F:y{s3:xWItfa=:b9yIWSfs-'V^ xqIwzqzF t\`&$V'Y\SS1S57v3Q޵y"D[>ǩe;Sז l_e?iF۬~}4LϤ|D*q Oײ}zڌ#wwڦ: 4#s~+=/+Qff:ҀPFt^mڵcXŊIa^i خ)&ꆃƒF@#Vk@D Ȝ>ΞAYK,44 K[[a̩a DsxweeAG oG*[YeGY޻ [ߊ9lwNFjt9wC!jLOIcV:F^\@,#cU8!t]HgT+aW(ԇDz# 4u84+<&rP-Tf~6 s9|w#6oܷێm7f/E-Lt% OگhvL$Hbrvmg&Ty]Wc ap0^QzAXCUnJg @j%icD% +0TyN;0ֻ9+|R.[o+0_52H\ tc09T[\ _OeTm)34FStWh,mHԷ;5z.QOh,ig]a BB QAdΜpЩgǝ31m2Sɲ;, )e: oJ&GaV); Y4LFFC1jy`cw|T:tp !nUZcJ]vr_j!0>[&&k՝g}ML][h䑇z:js-T_Wommx [ea6fq#[.ɵ1Yoim@sbAphڬW ুp_>\?kdΣ}*=?D`S4צv=R7 ^g({zYΫse|;//Q'|p=#x3"QB{Li*{'#9@m~0fzmw '0FF6FʴяӪ37_mZ1E9S&/nuwxD^v>R{TV^P =ׯm15@8[-ۡ H`\(P-]n Tj*z?")׊G"/Li>!4xq-Z"PRRä<05T9q jط{t\-P $C7+xZaR!lKDF>"< tEWZss04X&ђ+_zNY=EҫgDHnjѿᆦ.+Vou=:1Lv d\#̢AOа3 7htC?3Β' SӒhJL+q IOpŒE('r<2A *QF&yUg[`ldt|lQ5H}eOPܾ<~ JWK08w>ڡLwgϏ nDBR;XcmĺF] oQg7k-2&:EF#!ash  mDͩשG4 !"iL)w/5L~G.5?M'AXOg;:5|3 8%0 ,# ;?E0y롣'xa~a 9>BĪv+Nv;63uS _ |3B^p;RGJ'֨wPkV@ohz%,=5t&~zpfg];v?_fI *7-4,F:a:kM=:;.bK kO‹|(η>lc ?nluؙ9qR`s9%//>x" K}gGd?gܚ;?Z,͈^[^e/>Ofx";zgg'ffג0!(E)i.6zW7 xQ4Q3bhYt0,.ü(%ޜ ?OqwB{JZ0fox<{Jlyg28}Ng p,n2#[i''gK灬 ,L/<OR?_Բk#>gk*it<&ZObmM%A& ?Ĕ1/9qҐ!vz%sG!\W+j*>-l$)3=4>4Lu`ԧ"qgXMW׈c "p.sgyϾ:vKcWiF@߭ܛvl/X^!ze)tv1f8<:{SC'É|OFӠ`7Ȅp)߅K;oC`ni}A SNgԓiFKt?sJ˹9ݔ+ $ {?e/`S*+VV豿_"=cB{׫dwC`k! |_#q T؎9$nghQRھ΢7JL8 0tuwˎ9`_xL!N` [vWgz͋zn 3P[v#lspsrs20C \1S;Ӭ<\w}|F=o7̒sb',.!<`n4 V#R^ۗ, ̢X ^+ew]8hyj3s|[+jrm5ۯ=(NHh:CL/kFLy6x5Sφ4jbt 76=|"NWy?vhd] "fa05FPP 4P?psYQUU?2I]]sMC]mFDx'~ u3mnzH,aR@\wg0BSNlsw?j}S.W~&f r^(RѰ޾M:q46a~@Ν{J}'u=uz9|mc03ћhDlwa #e;t!; e⧵k?ՉA{a睅Sʷr22_z"vZivLd۩=Y!fίWE,퀎Fa|&#Gc=NX٣9^Ly(_p2MS>=ԻJ4c#&†$| ;ct[0gpFY;2!XμVoE`n*OuR1u^eaJ_F:ӻM4!1&f" !cñFֻ>#{z`'eρ`2ۃS^zYgI羽Cfdb4QĻ=7鍥#jwdFG(-Ow=Tm"Goxp{atx:2wEI^^0)0%^ſ׼sf_zs+A (8Ԣʔ CȓkDx`~8 {za}%HZ#͞6,<:wcDGj0_!+Z'ggP< ! a ⾘IDO_[b61BXza^k(cd>JН@iSǜM,;j0Xs|<iaՃ  _^wݳi׍k` Xfl1P3sϳIT+lH!0?GLR)D/L[:#?{f7*IA7 ԋɏ2*QWzPhZ q"<Cj7:Fº5Ǽ3Q8="Vш]oϽwf:T!(̟!ƏdlLe5ba ˙{kl]iqpQ]Ԝ'CN3@pRk4(LK7<"TOeZA/g(sbF5="^B׸'p`bC cI+IVF$ϏǴ\h[_C4i.n@܎u1)',~ F!-V`YNzy-Lی<5'876exa73L0`Q6%b@375uTgy |0i"byuQSV}^V7qa;e_}_G xwϾ wywێi<]6a]&{ hjp<ڧs[v<Ҹ+6wW휨|(bG-VW_vz0m&[W:3U'o-Z#eF=k讶!2E3m 聘!SԼϢ(̩ o{LÚf cҢ@C"?u?GXe^kj^;}Rjs=%!3skk < ,]. yB*Q~{xz;4< ?E!L+Lo Rrp@;J qyH&ܴy4 4v\4M/0Vem֛Ȉ.B`…"<{Q?x m^36]ɽw"bZIz(sTE{#nҶV9_O;|~C]g"p34ޞ{%z8q29[:Z15m5]7_9H xŊAJR`uziRHk #qNE(X$ɼyX3];;cdBOhi24^/`,cy9"bUQZPi7LJ!׼DEr Z˼fB;~Dü!gEdגi@BT`4 t-npf!8\R>'FBA2ldpwZi8~ۂl?@A'mdJ?p'>.Cu/U}U6&3ϖ"uQjX{N,|3%O͔wj6/ #NwQ ix/{gEc.<&ϰӥX[DM5A=oC ˷UԹ3bBTϽ6Ȼ_u~ezHm59m'B•A;g?h͹C9 2tq?&0ٷV kv!VqTQ ,0߫,s;+Oa_|%cnL/ߏ^v7WLayMf!Rt9R^Kan̎ᮤ^B=N"cYSzW7C.ȢB$|'fo~ۓo0W^ eF,/Ulu qvk,HuIdߑ IN{Kг@U]H#l QRO8A37nܰ2jWɪdΑv<5G_mP1M[㝚X`쮬^[2Ya8v'bxc@"28V)Ϫ{kY-.楤۱=x1u@Yphhy-mch]T!F31ݹۦ!#iCz浕k,Z;nOHMV8K‹}c)xzb]w%Sd8H8`/hت1p2;ۻf?z]̋,^D9RWyZȅk@20 >Ȫ4'~fo{[kȽ?B苿:YEFp%8 #ZUoŽiCN[ #_>wv6|칧Zkə}{_ +&5ɻ?gk~7`o( |A@.DnW4/5{V ̌%l'}~M/ʂ6>z_7gJM<|x ceivNLv ~NB^T˽yĤ2]5fNni.g@$*.|67hE%N]77A|qUH+7OޏwD gb&2lePlz'Vs^3ML$o;'8[͔jymu$e氦4[k\/̡.JM^kñCA*m?"BRzUT旕1ԯD < ,`0bϥ\4ֺs+Nrzv*`=m=S2!$X )823Q ;a+3vb$v锤2D'#mQqx0jbźGKPqbiw;?la^$.8 _85qڼ }p sY5k Tq7n&['g^%`os$XcJ'4Lp b g26[a{k6`pwLŏo{(@|)иSVq٬a/G6IN7g(iU\ ^D\r'u_eY e'㧰zs=*B@"*EX_<}HxcሠM!(3<3S>k)LO[1R)|%gp=$]%#XtJRXTYY+36ȼf2/^ڜѻ@U㛡{ukׂFkkULzHz/d j~MX/Zf> =ZGZWh>]NЕ̵ɲWa^^{^f. G3oݻE6F JXÜi*Oż2.Ֆ]R6 աap]#y2ߚt+FYpNz^]2W𵺭OVrtEg4~Ri?<% ޼7:>vMkEf^;RyjjUB Yא.G׆ym9dƢ4Q V416c\O hCX=(9{6Ahmlh(aB5Im[lbmes*eNQ4 sImhw L0e"2\6A$481-x0S Lt"=ڥf_7_bq~ĵAHY1_-nB[dyD<0O٘iO,Ccka> )5D0 >>sxGN=C+hD-bOY_V??{[<.Cg+g?C?BD\7O?nWV72&Bu; -}kQ=E ?335J.gVS>-ko-.^^w-Mpkǭ;OOkǩpN,{(ȗ7K@z+??,+ eYLgZ`vMZ" 0Լ3+F//%"ImQ iV,/ vz^SaڼF{QsXKmq衲 ,,ldGmW*@E:@J# ozSbC!bhb 0 -V֏rP+XP/J w:V[+gOeqŁ v/r:=̗Fb::z?C[;([Fr1;6zeN\+C@NRͽ!.TɁ1m1|$B: t}mru#kGf0kt%s#|.ܾY ؞:_}aFH=esnYZL4FWh5Mr_~j8afQ)k]v|q[ݕ\P+"ƁFrss(!0e4q+ymԌ;ЎX<"˲ 3\l"@ 7LhFT>YβQ9LBb4/m9D,q#7>长9z ޵-?|nT+TMh Ab!p| QΝ_30gL  ٠c}غ)_2u(7RZgOM_0T{ʨ!LfFX0ȻoF'k )Ɖ| ((3zR_8ՀZorg:Q~a`n ܱ|B+gaGp&0_lգo^U޼W6p 8K f'!aQx=E@lXUPUB5hAe~ψq,_#E~qW[[W[ha[4"ͼ}+ou3=D-SO+?4{\4?y7Goŝ2H;]fv~˚A㞠Sn\L :eGtBW=ii:E||i<_!-ֺ.<".w]?w<4Z#x?.V#6Q݇8sgE҉Y(_w ~(1i;'*wҬU\_c=͇`e%Ђl2w?Y3̅{gV.ZÙ/;]CyCsmQ@{L13az,xc^$_m^6m_A9QoS2e7Weu_ +eom:46۴AB@>E'@>B7q;,`SP.i G_0]B;bnL6s5+4⻛!gdl5Ķ bߕ Z0MvC~ ? Yѓe|~?v)W[Bѳc\tVOvu|0m؜.|i,TxΪYv̎oJ6<_qXy2#!IJ=g~k̰hcYaE)̷ћYJ|yO T1 \W (zjY:BCh썵9~6:~bWv9tf1ZHMZQi_1k4R.Ҟ/g`w!g!9sI5*GymzĐ;LaF3&A00^(-= Q~m:⥡Fɶ=w!od)dWvTݶpo 2ÍlD^m8=y\?HcHQfJ8cB+˧(9OܐMRk\=˱!z"u !\4Go(!笱+lL,a+W|Lύ; 1ϙasw.3jZSjrG# lj}ʬtNM8#A}1Ƶ>+k;/x ^h)y+p6Z]i+Bg?RE,A@1_ :a׋=w*2@6ߍ}p|)Fg0NۢaQ_z2YwڑDF ޽~),(Hj݊T+Q!ȟɟ^鎍.q.xӛ%eYq5kΝ~qvٛ itGG]K\1m<1>^fg.mn;;Mټޝ6|Ƅlӄ "PJ "<ņe~(t͞뭝a#O&ʭIFxF8޵}۳O_.ʽт/'\:{5<f_o6UO?3OFɈ+Mv3 B GI$E9W3\vP,I<#Q@iW^z^TLPqa/ˎ_=]uOrq6Sp5#3Na(^wCSP|.)/\(yk C'^FCslʩ3qL c\{䝸Zn³ϔ`0,}gBcibۗg>\<ҚgY 1vO$T~.홳9fȡs<]f{z̄ «!69o@Z0SI̱{nn̵섧ф^6~w? u]k1ȖńG.8L'gfom+;pŋf8h#h퇖69W2BF=:;/yrE(MDxvj@uxkxOI4̲S'2 _4"rPmZ08h=f뭛CGajBO,RW;`#4[3^xn5,nn"Y:TƴwQOl飱Cdc)@q62{Ӱ??n '0\⁖w}CnUaRa^s|WYv/% H5DlrIF*oU["jOcCZB {ۑ .S$$UdDASllU;xTj=0?OW{'kTo"bJrww=2^a ʂ.ły=7Yi7q?=x8rV9_N.]'H' r]Gw?uw)\(Gtu lJSStЂm$Og0-W]Fûi<ֻCW[/;|]N_1ꭻ4b&f"$(ĩ1дGH$ e}+y}7]vZ^07CunWʰD;1FwAo;Qm^z)x?0)wMA6YAyY܆UoQ;_eE[S4ĕcԄ,at0ػ!#yI~;Sx(\NNԡY}o[𧽌Z^[[h~h!'i+FA\i$tt[X3ū2\eկ&cvNRFp-'F {?=?X rI `B-|6 &? r?"WPi~ٰbӄ9}71PlA!5*G얧tJͳ+ieHrsh4։/`pU^Ƒn+f5MI#$ZK #+:MLƲ\ZkD[G2ҳ%ݟ2F"ix׈Rn/ΔPη :O>zx]+:: ,0,Dɫ;CP;eZt;xS\_#'Z$c hz] {v UHڑ$ϦWQ!G6zj ]9,[HoݾS.]mP{+$2dIPA@ܕ+: 6d)U]9#mPy IDAT 7!X)Xv3zԺasFn( 녲P/!myL fdCYnCs%096p,R33Q0Z7_V/x2 5׳u;x?a?9}IP[ ;1cNgJb -ӥi./ǀ2CSj[qڿmHu_[ 0I w&KjOfnw¾#X;n ڬ$3(1 p*3sZN4G G^vAZC Jmd̈BŨ`941oٞB{h2يjO-ܞ<,,&O< vo8 1ZOmPNl|4 FyJ ;#.{۳ #6Zrp</ږnR7;Ɏyps3y-oX p_ uTq#_um` L7"0ovh߷[ƞo8NuxՂܶw Kof.fu/3˺r+EvZ ~4y_I 3mФy]B^*szR6 Ն`K҆QƱ 7c=¤v9-2e'X֭_@G3/۽j%$/5#!\:ѺQ]`ToG[?Uݸ\Wы"y@ͨ3sRN-d T5tS՛(ev;A`=WoNHa}'M0^EkӨ#d w0v"1T_km2*Ωvr5 3@탆'Nj apCN.p7HkI \% IyZٗ|_y[z4>O'pXc&s a]4>`@S"WbD .L4 \ # |tpGXcG+a&&BNFp%)IoVe%CTkq/ͼ73>ڿ n4iKj֨,x߀c0'Pt.]HpVELvdD9lyڢ0&md0 FTC\VMY^(Aݏ|3vBԯϜ́ސU4gSQ7G( 9:{\gxŽρ X/e!O~'Ĺ,Xz秘(n<DO17Py'~7AKSkGf>U]9 FU<53rAT= ]ho8<̞5LLVi4Pxoa` Q<Dn7km7km7km7km7km7&;xn*&k-p0c̕Md,p)Fg{6~Uƽa{𭬉8- laÇZ(^q0wKýf}>;ώn2җ_mO|m&߭8[kǀ-lAX_xvỗr4 rqrcode-1.2.0/lib/000077500000000000000000000000001377164011400137235ustar00rootroot00000000000000rqrcode-1.2.0/lib/rqrcode.rb000066400000000000000000000002351377164011400157070ustar00rootroot00000000000000# frozen_string_literal: true module RQRCode require 'rqrcode_core' require 'rqrcode/qrcode' require 'rqrcode/export' require 'rqrcode/version' end rqrcode-1.2.0/lib/rqrcode/000077500000000000000000000000001377164011400153625ustar00rootroot00000000000000rqrcode-1.2.0/lib/rqrcode/export.rb000066400000000000000000000002251377164011400172270ustar00rootroot00000000000000# frozen_string_literal: true require 'rqrcode/export/ansi' require 'rqrcode/export/html' require 'rqrcode/export/png' require 'rqrcode/export/svg' rqrcode-1.2.0/lib/rqrcode/export/000077500000000000000000000000001377164011400167035ustar00rootroot00000000000000rqrcode-1.2.0/lib/rqrcode/export/ansi.rb000066400000000000000000000040411377164011400201610ustar00rootroot00000000000000# frozen_string_literal: true module RQRCode module Export module ANSI # # Returns a string of the QR code as # characters writen with ANSI background set. # # Options: # light: Foreground ("\033[47m") # dark: Background ANSI code. ("\033[47m") # fill_character: The written character. (' ') # quiet_zone_size: (4) # def as_ansi(options={}) options = { light: "\033[47m", dark: "\033[40m", fill_character: ' ', quiet_zone_size: 4 }.merge(options) normal = "\033[m\n" light = options.fetch(:light) dark = options.fetch(:dark) fill_character = options.fetch(:fill_character) quiet_zone_size = options.fetch(:quiet_zone_size) output = [] @qrcode.modules.each_index do |c| # start row with quiet zone row = light + fill_character * quiet_zone_size previous_dark = false @qrcode.modules.each_index do |r| if @qrcode.checked?(c, r) if previous_dark != true row << dark previous_dark = true end row << fill_character else # light if previous_dark != false row << light previous_dark = false end row << fill_character end end # add quiet zone if previous_dark != false row << light end row << fill_character * quiet_zone_size # always end with reset and newline row << normal output << row end # count the row width so we can add quiet zone rows width = output.first.scan(fill_character).length quiet_row = light + fill_character * width + normal quiet_rows = quiet_row * quiet_zone_size return quiet_rows + output.join + quiet_rows end end end end RQRCode::QRCode.send :include, RQRCode::Export::ANSI rqrcode-1.2.0/lib/rqrcode/export/html.rb000066400000000000000000000022261377164011400201760ustar00rootroot00000000000000# frozen_string_literal: true module RQRCode module Export module HTML # # Use this module to HTML-ify the QR code if you just want the default HTML def as_html ['', rows.as_html, '
'].join end private def rows Rows.new(@qrcode) end class Rows < Struct.new(:qr) def as_html rows.map(&:as_html).join end def rows qr.modules.each_with_index.map { |qr_module, row_index| Row.new(qr, qr_module, row_index) } end end class Row < Struct.new(:qr, :qr_module, :row_index) def as_html ['', cells.map(&:as_html).join, ''].join end def cells qr.modules.each_with_index.map { |qr_module, col_index| Cell.new(qr, col_index, row_index) } end end class Cell < Struct.new(:qr, :col_index, :row_index) def as_html "" end def html_class qr.checked?(row_index, col_index) ? 'black' : 'white' end end end end end RQRCode::QRCode.send :include, RQRCode::Export::HTML rqrcode-1.2.0/lib/rqrcode/export/png.rb000066400000000000000000000112131377164011400200120ustar00rootroot00000000000000# frozen_string_literal: true require 'chunky_png' # This class creates PNG files. # Code from: https://github.com/DCarper/rqrcode module RQRCode module Export module PNG # Render the PNG from the QR Code. # # There are two sizing algoritams. # # - Original that can result in blurry and hard to scan images # - Google's Chart API inspired sizing that resizes the module size to fit within the given image size. # # The Googleis one will be used when no options are given or when the new size option is used. # # Options: # fill - Background ChunkyPNG::Color, defaults to 'white' # color - Foreground ChunkyPNG::Color, defaults to 'black' # # When option :file is supplied you can use the following ChunkyPNG constraints # color_mode - The color mode to use. Use one of the ChunkyPNG::COLOR_* constants. defaults to 'ChunkyPNG::COLOR_GRAYSCALE' # bit_depth - The bit depth to use. This option is only used for indexed images. defaults to '1' bit # interlace - Whether to use interlacing (true or false). defaults to ChunkyPNG default # compression - The compression level for Zlib. This can be a value between 0 and 9, or a Zlib constant like Zlib::BEST_COMPRESSION, defaults to ChunkyPNG defaults # # *Googleis* # size - Total size of PNG in pixels. The module size is calculated so it fits. (defaults to 90) # border_modules - Width of white border around in modules. (defaults to 4). # # -- DONT USE border_modules OPTION UNLESS YOU KNOW ABOUT THE QUIET ZONE NEEDS OF QR CODES -- # # *Original* # module_px_size - Image size, in pixels. # border - Border thickness, in pixels # # It first creates an image where 1px = 1 module, then resizes. # Defaults to 90x90 pixels, customizable by option. # def as_png(options = {}) default_img_options = { bit_depth: 1, border_modules: 4, color_mode: ChunkyPNG::COLOR_GRAYSCALE, color: 'black', file: false, fill: 'white', module_px_size: 6, resize_exactly_to: false, resize_gte_to: false, size: 120 } googleis = options.length == 0 || (options[:size] != nil) options = default_img_options.merge(options) # reverse_merge fill = ChunkyPNG::Color(options[:fill]) color = ChunkyPNG::Color(options[:color]) output_file = options[:file] module_px_size = nil border_px = nil png = nil if googleis total_image_size = options[:size] border_modules = options[:border_modules] module_px_size = (total_image_size.to_f / (@qrcode.module_count + 2 * border_modules).to_f).floor.to_i img_size = module_px_size * @qrcode.module_count remaining = total_image_size - img_size border_px = (remaining / 2.0).floor.to_i png = ChunkyPNG::Image.new(total_image_size, total_image_size, fill) else border = options[:border_modules] total_border = border * 2 module_px_size = if options[:resize_gte_to] (options[:resize_gte_to].to_f / (@qrcode.module_count + total_border).to_f).ceil.to_i else options[:module_px_size] end border_px = border * module_px_size total_border_px = border_px * 2 resize_to = options[:resize_exactly_to] img_size = module_px_size * @qrcode.module_count total_img_size = img_size + total_border_px png = ChunkyPNG::Image.new(total_img_size, total_img_size, fill) end @qrcode.modules.each_index do |x| @qrcode.modules.each_index do |y| if @qrcode.checked?(x, y) (0...module_px_size).each do |i| (0...module_px_size).each do |j| png[(y * module_px_size) + border_px + j , (x * module_px_size) + border_px + i] = color end end end end end if !googleis && resize_to png = png.resize(resize_to, resize_to) end if output_file constraints = { color_mode: options[:color_mode], bit_depth: options[:bit_depth] } constraints[:interlace] = options[:interlace] if options.has_key?(:interlace) constraints[:compression] = options[:compression] if options.has_key?(:compression) png.save(output_file, constraints) end png end end end end RQRCode::QRCode.send :include, RQRCode::Export::PNG rqrcode-1.2.0/lib/rqrcode/export/svg.rb000066400000000000000000000043001377164011400200240ustar00rootroot00000000000000# frozen_string_literal: true # This class creates a SVG files. # Code from: https://github.com/samvincent/rqrcode-rails3 module RQRCode module Export module SVG # # Render the SVG from the Qrcode. # # Options: # offset - Padding around the QR Code (e.g. 10) # fill - Background color (e.g "ffffff" or :white) # color - Foreground color for the code (e.g. "000000" or :black) # module_size - The Pixel size of each module (e.g. 11) # shape_rendering - Defaults to crispEdges # standalone - wether to make this a full SVG file, or only svg to embed # in other svg. # def as_svg(options={}) offset = options[:offset].to_i || 0 color = options[:color] || "000" shape_rendering = options[:shape_rendering] || "crispEdges" module_size = options[:module_size] || 11 standalone = options[:standalone].nil? ? true : options[:standalone] # height and width dependent on offset and QR complexity dimension = (@qrcode.module_count*module_size) + (2*offset) xml_tag = %{} open_tag = %{} close_tag = "" result = [] @qrcode.modules.each_index do |c| tmp = [] @qrcode.modules.each_index do |r| y = c*module_size + offset x = r*module_size + offset next unless @qrcode.checked?(c, r) tmp << %{} end result << tmp.join end if options[:fill] result.unshift %{} end if standalone result.unshift(xml_tag, open_tag) result << close_tag end result.join("\n") end end end end RQRCode::QRCode.send :include, RQRCode::Export::SVG rqrcode-1.2.0/lib/rqrcode/qrcode.rb000066400000000000000000000000771377164011400171700ustar00rootroot00000000000000# frozen_string_literal: true require 'rqrcode/qrcode/qrcode' rqrcode-1.2.0/lib/rqrcode/qrcode/000077500000000000000000000000001377164011400166375ustar00rootroot00000000000000rqrcode-1.2.0/lib/rqrcode/qrcode/qrcode.rb000066400000000000000000000005171377164011400204440ustar00rootroot00000000000000# frozen_string_literal: true require 'forwardable' module RQRCode #:nodoc: class QRCode extend Forwardable def_delegators :@qrcode, :to_s def_delegators :@qrcode, :modules # deprecated attr_reader :qrcode def initialize(string, *args) @qrcode = RQRCodeCore::QRCode.new(string, *args) end end end rqrcode-1.2.0/lib/rqrcode/version.rb000066400000000000000000000001061377164011400173710ustar00rootroot00000000000000# frozen_string_literal: true module RQRCode VERSION = "1.2.0" end rqrcode-1.2.0/rqrcode.gemspec000066400000000000000000000024441377164011400161650ustar00rootroot00000000000000# -*- encoding: utf-8 -*- lib = File.expand_path("../lib", __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require "rqrcode/version" Gem::Specification.new do |spec| spec.name = "rqrcode" spec.version = RQRCode::VERSION spec.platform = Gem::Platform::RUBY spec.authors = ["Duncan Robertson"] spec.email = ["duncan@whomwah.com"] spec.summary = %q{A library to encode QR Codes} spec.description = < 0.2' spec.add_dependency 'chunky_png', '~> 1.0' spec.add_development_dependency 'bundler', '>= 2.0' spec.add_development_dependency 'rake', '~> 13.0' spec.add_development_dependency 'rspec', '~> 3.5' end rqrcode-1.2.0/spec/000077500000000000000000000000001377164011400141075ustar00rootroot00000000000000rqrcode-1.2.0/spec/rqrcode/000077500000000000000000000000001377164011400155465ustar00rootroot00000000000000rqrcode-1.2.0/spec/rqrcode/data.rb000066400000000000000000000676041377164011400170210ustar00rootroot00000000000000 AS_ANSI = <<-ANSI.chomp \e[47m \e[m\n\e[47m \e[m\n\e[47m \e[m\n\e[47m \e[m\n\e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[m\n\e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[m\n\e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[m\n\e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[m\n\e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[m\n\e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[m\n\e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[m\n\e[47m \e[40m \e[47m \e[m\n\e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[m\n\e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[m\n\e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[m\n\e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[m\n\e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[m\n\e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[m\n\e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[m\n\e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[m\n\e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[m\n\e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[m\n\e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[m\n\e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[m\n\e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[40m \e[47m \e[m\n\e[47m \e[m\n\e[47m \e[m\n\e[47m \e[m\n\e[47m \e[m\n ANSI AS_SVG= <<-SVG.chomp SVG AS_BASIC= <<-STR XXXXXXXOOOXOXOOXXXOOOOXXXXXXX XOOOOOXOOXXXXXOOXOXOOOXOOOOOX XOXXXOXOOOOXOXOOOOOXOOXOXXXOX XOXXXOXOOXXXOOXOXXXOOOXOXXXOX XOXXXOXOXXXOOXOOXOOXOOXOXXXOX XOOOOOXOOOXXOOXXOXXXXOXOOOOOX XXXXXXXOXOXOXOXOXOXOXOXXXXXXX OOOOOOOOXXXOXXOXXOOOXOOOOOOOO OOXXOOXXXOOXOXOXOOXXOXXOXOOOO XXOOXXOOXOXXXOOOOOXOXXOXOXXOX XOXOOXXXXXOXXOOXXOXXXXXXXXOXO OOOOOOOXXOOOXOOOOXXOXXOXXOOOX XXXOXXXOXOOXOXOOOXOXOXOOOOXXX XOXXXXOOXOOOXXOXXOOXOOXXOXXOX XOOXXXXXOOXOOOOOOXXXXOXOXXOXX OOOOOOOXXXOXXOXOXOXOOOOOOXOOX XOOOXOXOXXXXXOXOOXXXOOOOOXOOO OOOXOXOXOOOOOOOXOOXXOXXOOOXOO XOXXOOXOXXOOXXOXOXOOXOXXXXOOO OOXXXXOXOXXXXXXOXOXOXXXXOOXXX OXOXXOXXOXXXOOOXXXOXXXXXXXOXO OOOOOOOOXOXOXOOXOOXXXOOOXXOXX XXXXXXXOXOXOOOOXXOOXXOXOXOXXO XOOOOOXOOOXOOXOXXOXOXOOOXOOOO XOXXXOXOOXOOOXXXOOOOXXXXXXXOX XOXXXOXOXXXXOXOOXXXXOXOOXXOOO XOXXXOXOXOOOXOOXOOOXXOOOOXXOX XOOOOOXOOXXOXXOOOOOOOOXOXXXXO XXXXXXXOOOXXXXOOOOXXOOXXOOXXO STR AS_HTML= <<-HTML.chomp
HTML rqrcode-1.2.0/spec/rqrcode/export_ansi_spec.rb000066400000000000000000000004231377164011400214370ustar00rootroot00000000000000require 'spec_helper' require 'rqrcode/data' describe 'Export::ANSI' do it 'must respond_to ansi' do expect(RQRCode::QRCode.new('x')).to respond_to(:as_ansi) end it 'must export to ansi' do expect(RQRCode::QRCode.new('ansi').as_ansi).to eq(AS_ANSI) end end rqrcode-1.2.0/spec/rqrcode/export_html_spec.rb000066400000000000000000000003771377164011400214610ustar00rootroot00000000000000require 'spec_helper' describe 'Export::HTML' do it 'must respond_to html' do expect(RQRCode::QRCode.new('html')).to respond_to(:as_html) end it 'must export to html' do expect(RQRCode::QRCode.new('html').as_html).to eq(AS_HTML) end end rqrcode-1.2.0/spec/rqrcode/export_png_spec.rb000066400000000000000000000042251377164011400212750ustar00rootroot00000000000000require 'spec_helper' describe 'Export::PNG' do let(:mockImage) { double(:mock_image) } before :each do allow(mockImage).to receive(:[]=) end it 'must respond_to png' do expect(RQRCode::QRCode.new('x')).to respond_to(:as_png) end it 'must export to png file' do expect(RQRCode::QRCode.new('png').as_png).to be_instance_of(ChunkyPNG::Image) end it 'must export a png using the correct defaults' do expect(ChunkyPNG::Image).to receive(:new) .once .with(120, 120, 4294967295) .and_return(mockImage) expect(mockImage).not_to receive(:save) RQRCode::QRCode.new('png').as_png end context 'with file save and constaints' do it 'should export using the correct defaults' do expect(ChunkyPNG::Image).to receive(:new) .once .with(174, 174, 4294967295) .and_return(mockImage) expect(mockImage).to receive(:save) .once .with('some/path', {bit_depth: 1, color_mode: 0}) RQRCode::QRCode.new('png').as_png( file: 'some/path' ) end it 'should export using custom constraints' do expect(ChunkyPNG::Image).to receive(:new) .once .with(174, 174, 4294967295) .and_return(mockImage) expect(mockImage).to receive(:save) .once .with('some/path', { bit_depth: 8, color_mode: 2, interlace: true, compression: 5 }) RQRCode::QRCode.new('png').as_png( color_mode: ChunkyPNG::COLOR_TRUECOLOR, bit_depth: 8, file: 'some/path', color: 'red', interlace: true, compression: 5 ) end it 'should save' do qrcode = RQRCode::QRCode.new("http://github.com/") png = qrcode.as_png( bit_depth: 1, border_modules: 4, color_mode: ChunkyPNG::COLOR_GRAYSCALE, color: 'black', file: nil, fill: 'white', module_px_size: 6, resize_exactly_to: false, resize_gte_to: false, size: 120 ) IO.binwrite("/tmp/github-qrcode.png", png.to_s) expect(IO.binread("/tmp/github-qrcode.png")).to eq png.to_s end end end rqrcode-1.2.0/spec/rqrcode/export_svg_spec.rb000066400000000000000000000023101377164011400213010ustar00rootroot00000000000000require 'spec_helper' require 'rqrcode/data' describe 'Export::SVG' do it 'must respond_to svg' do expect(RQRCode::QRCode.new('qrcode')).to respond_to(:as_svg) end it 'must export to svg' do expect(RQRCode::QRCode.new('qrcode').as_svg).to eq(AS_SVG) end describe "options" do it 'has standalone option true by default' do doc = RQRCode::QRCode.new('qrcode').as_svg # For now we do very naive pattern matching. The alternative is to # include a librariry for parsing XML, like nokogiri. That is a big # change for such a small test, though. expect(doc).to match(%r{<\?xml.*standalone="yes"}) expect(doc).to match(%r{}) expect(doc).to match(%r{}) end it 'omits surrounding XML when `standalone` is `false`' do doc = RQRCode::QRCode.new('qrcode').as_svg(standalone: false) # For now we do very naive pattern matching. The alternative is to # include a librariry for parsing XML, like nokogiri. That is a big # change for such a small test, though. expect(doc).not_to match(%r{<\?xml.*standalone="yes"}) expect(doc).not_to match(%r{}) expect(doc).not_to match(%r{}) end end end rqrcode-1.2.0/spec/rqrcode/qrqcode_spec.rb000066400000000000000000000025521377164011400205470ustar00rootroot00000000000000require 'spec_helper' require 'rqrcode/data' describe 'RQRCode' do it 'must provide a custom to_s' do qr = RQRCode::QRCode.new('http://kyan.com', size: 3) expect(qr.to_s[0..50]).to eq("xxxxxxx x x xxx xxxxxxx\nx x xxxxx x x ") expect(qr.to_s(true: 'q', false: 'n')[0..36]).to eq("qqqqqqqnnnqnqnnqqqnnnnqqqqqqq\nqnnnnnq") expect(qr.to_s(true: '@')[0..21]).to eq("@@@@@@@ @ @ @@@ ") end it 'must expose the core qrcode' do expect(RQRCode::QRCode.new('svg').qrcode).to be_instance_of(RQRCodeCore::QRCode) end it 'should do a basic render' do qr = RQRCode::QRCode.new('http://kyan.com') str = '' qr.qrcode.modules.each do |row| row.each do |col| str << (col ? 'X' : 'O') end str << "\n" end expect(str).to eq(AS_BASIC) end it 'should do a basic render using old "modules" interface' do qr = RQRCode::QRCode.new('http://kyan.com') str = '' qr.modules.each do |row| row.each do |col| str << (col ? 'X' : 'O') end str << "\n" end expect(str).to eq(AS_BASIC) end it 'should pass options to rqrcode_core' do options = { size: 5, mode: :alphanumeric } qr = RQRCode::QRCode.new('QRCODE', options) expect(qr.qrcode.mode).to eq(:mode_alpha_numk) expect(qr.qrcode.version).to eq(options[:size]) end end rqrcode-1.2.0/spec/spec_helper.rb000066400000000000000000000114601377164011400167270ustar00rootroot00000000000000# This file was generated by the `rspec --init` command. Conventionally, all # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. # The generated `.rspec` file contains `--require spec_helper` which will cause # this file to always be loaded, without a need to explicitly require it in any # files. require 'rqrcode' # # Given that it is always loaded, you are encouraged to keep this file as # light-weight as possible. Requiring heavyweight dependencies from this file # will add to the boot time of your test suite on EVERY test run, even for an # individual file that may not need all of that loaded. Instead, consider making # a separate helper file that requires the additional dependencies and performs # the additional setup, and require it from the spec files that actually need # it. # # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration RSpec.configure do |config| # rspec-expectations config goes here. You can use an alternate # assertion/expectation library such as wrong or the stdlib/minitest # assertions if you prefer. config.expect_with :rspec do |expectations| # This option will default to `true` in RSpec 4. It makes the `description` # and `failure_message` of custom matchers include text for helper methods # defined using `chain`, e.g.: # be_bigger_than(2).and_smaller_than(4).description # # => "be bigger than 2 and smaller than 4" # ...rather than: # # => "be bigger than 2" expectations.include_chain_clauses_in_custom_matcher_descriptions = true end # rspec-mocks config goes here. You can use an alternate test double # library (such as bogus or mocha) by changing the `mock_with` option here. config.mock_with :rspec do |mocks| # Prevents you from mocking or stubbing a method that does not exist on # a real object. This is generally recommended, and will default to # `true` in RSpec 4. mocks.verify_partial_doubles = true end # This option will default to `:apply_to_host_groups` in RSpec 4 (and will # have no way to turn it off -- the option exists only for backwards # compatibility in RSpec 3). It causes shared context metadata to be # inherited by the metadata hash of host groups and examples, rather than # triggering implicit auto-inclusion in groups with matching metadata. config.shared_context_metadata_behavior = :apply_to_host_groups # The settings below are suggested to provide a good initial experience # with RSpec, but feel free to customize to your heart's content. =begin # This allows you to limit a spec run to individual examples or groups # you care about by tagging them with `:focus` metadata. When nothing # is tagged with `:focus`, all examples get run. RSpec also provides # aliases for `it`, `describe`, and `context` that include `:focus` # metadata: `fit`, `fdescribe` and `fcontext`, respectively. config.filter_run_when_matching :focus # Allows RSpec to persist some state between runs in order to support # the `--only-failures` and `--next-failure` CLI options. We recommend # you configure your source control system to ignore this file. config.example_status_persistence_file_path = "spec/examples.txt" # Limits the available syntax to the non-monkey patched syntax that is # recommended. For more details, see: # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode config.disable_monkey_patching! # This setting enables warnings. It's recommended, but in some cases may # be too noisy due to issues in dependencies. config.warnings = true # Many RSpec users commonly either run the entire suite or an individual # file, and it's useful to allow more verbose output when running an # individual spec file. if config.files_to_run.one? # Use the documentation formatter for detailed output, # unless a formatter has already been configured # (e.g. via a command-line flag). config.default_formatter = "doc" end # Print the 10 slowest examples and example groups at the # end of the spec run, to help surface which specs are running # particularly slow. config.profile_examples = 10 # Run specs in random order to surface order dependencies. If you find an # order dependency and want to debug it, you can fix the order by providing # the seed, which is printed after each run. # --seed 1234 config.order = :random # Seed global randomization in this process using the `--seed` CLI option. # Setting this allows you to use `--seed` to deterministically reproduce # test failures related to randomization by passing the same `--seed` value # as the one that triggered the failure. Kernel.srand config.seed =end end