pax_global_header00006660000000000000000000000064151626240420014514gustar00rootroot0000000000000052 comment=291cecc3512f220129db341ae60477666ba43c79 rubyworks-ansi-291cecc/000077500000000000000000000000001516262404200152065ustar00rootroot00000000000000rubyworks-ansi-291cecc/.github/000077500000000000000000000000001516262404200165465ustar00rootroot00000000000000rubyworks-ansi-291cecc/.github/workflows/000077500000000000000000000000001516262404200206035ustar00rootroot00000000000000rubyworks-ansi-291cecc/.github/workflows/test.yml000066400000000000000000000006171516262404200223110ustar00rootroot00000000000000name: Test on: push: branches: [master] pull_request: branches: [master] jobs: test: runs-on: ubuntu-latest strategy: matrix: ruby: ['3.1', '3.2', '3.3', '3.4'] steps: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} bundler-cache: true - run: bundle exec rake demo rubyworks-ansi-291cecc/.gitignore000066400000000000000000000000531516262404200171740ustar00rootroot00000000000000.yardoc doc log pkg tmp Gemfile.lock *.gem rubyworks-ansi-291cecc/.yardopts000066400000000000000000000000741516262404200170550ustar00rootroot00000000000000--title ANSI --protected --private lib - QED.rdoc [A-Z]*.* rubyworks-ansi-291cecc/Gemfile000066400000000000000000000000461516262404200165010ustar00rootroot00000000000000source "https://rubygems.org" gemspec rubyworks-ansi-291cecc/HISTORY.md000066400000000000000000000154031516262404200166740ustar00rootroot00000000000000# RELEASE HISTORY ## 1.6.0 | 2026-03-30 Maintenance release. Modernized project tooling and cleaned up documentation. Changes: * Replace custom Indexer system with standard gemspec. * Replace Travis CI with GitHub Actions. * Replace Assembly/detroit/ergo with Rakefile. * Simplify version.rb to use a plain constant. * Fix Fixnum reference for Ruby 3+ compatibility. * Fix typos and update URLs to HTTPS. * Move site from gh-pages to docs/. * Remove obsolete files. * Clean up .gitignore. ## 1.5.0 | 2015-01-16 ANSI 1.5 introduces one change that is not backward compatiable. The `:clear_line` code no longer clears to the end of the line. Instead it clears the entire line. If you have used this in the past you will need to update your code to use `:clear_eol` or `:clear_right` instead. In addition this release finally fixes some long time issues with Windows compatability, and a few other bugs. Yeah! Changes: * Alias `:right` and `:left` as `:forward` and `:back` respectively. * Change `:clear_line` to clear whole line, not just to the end of line. * Add `:cursor_hide` and `:cursor_show` codes. * Fix and adjust #rgb method to work as one would expect. * Fix Windows compatability (old code was alwasy using stty). * Fix duplicated hash key in chart.rb. ## 1.4.3 | 2012-06-26 This release bring two small changes. The first improves support for Windows by only rescuing LoadError when 'win32console' fails to load. The second improves the heuritstics used for determining the current terminal screen width. Changes: * Only rescue LoadError on windows require. (#9) [bug] * Improvements for getting proper screen width. ## 1.4.2 | 2012-01-29 ANSI chains are a new feature inspired by Kazuyoshi Tlacaelel's Isna project. It is a fluid notation for the String#ansi method, e.g. `"foo".red.on_white`. Also, ASNI now supports "smart codes", preventing previously applied codes from undermining the applicaiton of additional codes --a subtle issue that most other ANSI libraries overlook. Plus a few other improvements including that of the API documentation. Changes: * Add ANSI::Chains, extending String#ansi method. * Support smart code application. * Add Diff#to_a and shortcut to it via Diff.diff(). * Improve #colorize method in ProgressBar. * Change ProgressBar's default mark to `|` instead of `o`. * Fix Curses return order of screen cols and rows. * Support center alignment in Columns. * Support custom padding for Columns. ## 1.4.1 | 2011-11-09 This release simply fixes a documentation issue, to make sure QED.rdoc appears in the YARD docs. And a shout-out to Chad Perrin for submitting some doc fixes for this project and a few other Rubyworks projects. Changes: * Adjust .yardopts file. * Documentation fixes. ## 1.4.0 | 2011-11-05 New release adds a HexDump class for colorized byte string dumps and fixes some minor cell size issues with the Table class. This release also modernizes the build config and changes the license to BSD-2-Clause. Changes: * Add HexDump class. * Fix cell size of tables when ANSI codes are used. * Fix extra ansi codes in tables without format. * Modernize build configuration. * Switch to BSD-2-Clause license. ## 1.3.0 | 2011-06-30 This release cleans up the Code module. It adds support for x-term 256 color codes. Also, the Diff class is now awesome, making use of an LCS algorithm. But the most important difference with this release is that the String core extensions are in their own file, core.rb. If you want to use them you will need to require `ansi` or `ansi/core`. Changes: * Clean-up Code module. * Utilize common chart for Code methods. * Constants now have their own module. * Move core methods to `ansi/core.rb`. * Add XTerm 256 color code support. * Improved Diff class with LCS algorithm. ## 1.2.5 | 2011-05-03 This release introduces a preliminary rendition of a Diff class for getting colorized comparisons of strings and other objects. It's not officially supported yet, so this is only a point release. Changes: * Added Diff class for colorized comparisons. * Fixed minor issue with Columns format block; col comes before row. ## 1.2.4 | 2011-04-29 This release improves to the ANSI::Columns class. In particular the layout is more consistent with intended functionality. Changes: * Improved ANSI::Columns to give more consistent output. * ANSI::Columns#to_s can override number of columns. * ANSI::Columns can take a String or Array list. ## 1.2.3 | 2011-04-08 Minor release to add #clear method to ProgressBar and provide bug fix to BBCode.ansi_to_bbcode. Big thanks goes to Junegunn Choi for this fix. Changes: * Add ProgressBar#clear method. * Fixed ANSI::BBCode.ansi_to_bbcode and ansi_to_html from omitting lines without any ansi code (Junegunn Choi). ## 1.2.2 | 2010-06-12 This release removes warnings about string arguments for certain ANSI::Code methods. While the string form is considered deprecated, for a few methods there is no use for any argument, so the string form can remain. In addition, String#unansi has been added to compliment String#ansi. Lastly, this release also adds the #display method to ANSI::Mixin. Changes: * Remove string argument warnings. * Add String#unansi and String#unansi! * Add ANSI::Mixin#display. ## 1.2.1 | 2010-05-10 This release was simply a quick fix to remove the incorrect embedded version number, until it gets fixed. ## 1.2.0 | 2010-05-10 This release entails numerous improvements. First and foremost the Code module is transitioning to a block interface only and phasing out the string argument interface. Admittedly this is mildly unconventional, but it allows the arguments to be used as options with common defaults more elegantly. Another important change is that ANSI::Code no longer provides String extension methods when included. For this use the new ANSI::Mixin. Other improvements include a String extension, #ansi, added to code.rb, which makes it even easier to apply ANSI codes to strings. Also, the ANSI::String class has been fixed (a few bugs crept it with the last release) and continues to improve. On top of all this testing has substantially improved thanks to QED. Changes: * Support string argument for now but with warning * Bug fixes for ANSI::String * Add mixin.rb for alternate mixin. * Many new tests and QED documents. ## 1.1.0 | 2009-10-04 This release is the first toward making the ANSI library more widely usable. Changes: * Add bbcode.rb for conversion between BBCode/ANSI/HTML. * ProgressBar and Progressbar are the same. * Other minor underthehood improvements. ## 1.0.1 | 2009-08-15 The release fixes a single bug that should allow Ruby 1.9 to use the ANSI library. Changes: * Renamed PLATFORM to RUBY_PLATFORM ## 1.0.0 | 2009-08-15 This is the initial stand-alone release of ANSI, a collection of ANSI based classes spun-off from Ruby Facets. Changes: * Happy Birthday! rubyworks-ansi-291cecc/LICENSE.txt000066400000000000000000000024361516262404200170360ustar00rootroot00000000000000BSD-2-Clause License (http://spdx.org/licenses/BSD-2-Clause) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. rubyworks-ansi-291cecc/NOTICE.md000066400000000000000000000150731516262404200165170ustar00rootroot00000000000000# COPYRIGHT NOTICES ## ANSI Copyright © 2009 [Rubyworks](http://rubyworks.github.com) · License [BSD-2-Clause](http://spdx.org/licenses/BSD-2-Clause) · Website http://rubyworks.github.com/ansi Copyright 2009 Rubyworks. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (https://raw.github.com/rubyworks/ansi/master/LICENSE.txt) ## ProgressBar Copyright © 2001 *Satoru Takabayashi* · License [Ruby](http://spdx.org/licenses/Ruby) · Website http://0xcc.net/ruby-progressbar ProgressBar class is based on the original ProgressBar by Satoru Takabayashi. Ruby/ProgressBar - a text progress bar library Copyright (C) 2001-2005 Satoru Takabayashi All rights reserved. This is free software with ABSOLUTELY NO WARRANTY. You can redistribute it and/or modify it under the terms of Ruby's license. ## HighLine (Terminal Extensions) Copyright © 2006 *Gray Productions* · License [Ruby](http://spdx.org/licenses/Ruby) · Website http://highline.rubyforge.org The terminal extensions are based on HighLine's SystemExtensions by James Edward Gray II. Copyright 2006 Gray Productions Distributed under the user's choice of the {GPL Version 2}[http://www.gnu.org/licenses/old-licenses/gpl-2.0.html] (see GPL-2.0.txt for details) or the {Ruby software license}[http://www.ruby-lang.org/en/LICENSE.txt] by James Edward Gray II and Greg Brown. Please email James[mailto:james@grayproductions.net] with any questions. (https://github.com/JEG2/highline/blob/master/LICENSE) ## BBCode Copyright © 2002 *Thomas-Ivo Heinen* · License [Ruby](http://spdx.org/licenses/Ruby) BBCode module is a derivative of BBCode by Thomas-Ivo Heinen. Copyright (c) 2002 Thomas-Ivo Heinen This module is free software. You may use, modify, and/or redistribute this software under the same terms as Ruby. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ## Rainbow (XTerm Color Support) Copyright © *Marcin Kulik* · License [MIT](http://spdx.org/licenses/MIT) · Website http://github.com/sickill/rainbow Rainbox provided the bases for building the XTerm 256 color code support into the ANSI::Code module. Copyright (c) Marcin Kulik 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. (https://raw.github.com/sickill/rainbow/master/LICENSE) ## Paint (ANSI Code Names) Copyright © 2011 *Jan Lelis* · License [MIT](http://spdx.org/licenses/MIT) · Website https://github.com/janlelis/paint Some of the latest ANSI code names, and inspiration to check out Rainbow and include XTerm 256 color codes, came from Paint. Copyright (c) 2011 Jan Lelis 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. (https://raw.github.com/janlelis/paint/master/LICENSE.txt) ## ANSIColor _Acknowlegement_ Copyright © 2002 *Florian Frank* · Website http://flori.github.com/term-ansicolor Albeit the code no long bares much, if any, resemblance to it, the ANSI Code module (and subsequently the Constants module) originated with the ANSIColor library by Florian Frank. Copyright (c) 2002 Florian Frank rubyworks-ansi-291cecc/README.md000066400000000000000000000045761516262404200165010ustar00rootroot00000000000000# ANSI [HOME](https://rubyworks.github.io/ansi) · [API](https://rubydoc.info/gems/ansi) · [ISSUES](https://github.com/rubyworks/ansi/issues) · [SOURCE](https://github.com/rubyworks/ansi) [![Gem Version](https://img.shields.io/gem/v/ansi.svg?style=flat)](https://rubygems.org/gems/ansi) [![Build Status](https://github.com/rubyworks/ansi/actions/workflows/test.yml/badge.svg)](https://github.com/rubyworks/ansi/actions/workflows/test.yml)
The ANSI project is a collection of ANSI escape code related libraries enabling ANSI code based colorization and stylization of output. It is very nice for beautifying shell output. This collection is based on a set of scripts spun-off from Ruby Facets. Included are Code (used to be ANSICode), Logger, ProgressBar and String. In addition the library includes Terminal which provides information about the current output device. ## Features * ANSI::Code provides ANSI codes as module functions. * String#ansi makes common usage very easy and elegant. * ANSI::Mixin provides an alternative mixin (like +colored+ gem). * Very Good coverage of standard ANSI codes. * Additional clases for colorized columns, tables, loggers and more. ## Synopsis There are a number of modules and classes provided by the ANSI package. To get a good understanding of them it is best to pursue the [QED documents](https://github.com/rubyworks/ansi/tree/master/demo/) or the [API documentation](https://rubydoc.info/gems/ansi). At the heart of all the provided libraries lies the ANSI::Code module which defines ANSI codes as constants and methods. For example: require 'ansi/code' ANSI.red + "Hello" + ANSI.blue + "World" => "\e[31mHello\e[34mWorld" Or in block form. ANSI.red{ "Hello" } + ANSI.blue{ "World" } => "\e[31mHello\e[0m\e[34mWorld\e[0m" The methods defined by this module are used throughout the rest of the system. ## Installation ### Bundler Add the usual `gem` line to your project's `Gemfile`. gem 'ansi' And run then `bundle` command. ### RubyGems To install with RubyGems simply open a console and type: $ sudo gem install ansi ## Release Notes Please see HISTORY.md file. ## License & Copyrights Copyright (c) 2009 Rubyworks This program is redistributable under the terms of the *BSD-2-Clause* license. Some pieces of the code are copyrighted by others. See LICENSE.txt and NOTICE.md files for details. rubyworks-ansi-291cecc/Rakefile000066400000000000000000000006211516262404200166520ustar00rootroot00000000000000require 'rubygems/package_task' gemspec = Gem::Specification.load('ansi.gemspec') Gem::PackageTask.new(gemspec) do |pkg| pkg.need_zip = false pkg.need_tar = false end desc "Run QED demos" task :demo do sh 'bundle exec qed' end desc "Run unit tests" task :test do sh 'bundle exec ruby -Ilib -Itest -e "Dir.glob(\"test/case_*.rb\").each{|f| require \"./#{f}\"}"' end task :default => :demo rubyworks-ansi-291cecc/ansi.gemspec000066400000000000000000000016411516262404200175070ustar00rootroot00000000000000Gem::Specification.new do |s| s.name = 'ansi' s.version = '1.6.0' s.summary = 'ANSI at your fingertips!' s.description = 'The ANSI project is a superlative collection of ANSI escape code related ' \ 'libraries enabling ANSI colorization and stylization of console output. Byte for ' \ 'byte ANSI is the best ANSI code library available for the Ruby programming language.' s.authors = ['Thomas Sawyer', 'Florian Frank'] s.email = ['transfire@gmail.com'] s.homepage = 'https://github.com/rubyworks/ansi' s.license = 'BSD-2-Clause' s.required_ruby_version = '>= 3.1' s.files = Dir['lib/**/*', 'LICENSE.txt', 'README.md', 'HISTORY.md', 'NOTICE.md', 'demo/**/*'] s.require_paths = ['lib'] s.add_development_dependency 'rake', '>= 13' s.add_development_dependency 'qed', '>= 2.9' s.add_development_dependency 'ae', '>= 1.8' end rubyworks-ansi-291cecc/demo/000077500000000000000000000000001516262404200161325ustar00rootroot00000000000000rubyworks-ansi-291cecc/demo/01_ansicode.md000066400000000000000000000034421516262404200205440ustar00rootroot00000000000000# ANSI::Code Require the library. require 'ansi/code' ANSI::Code can be used as a functions module. str = ANSI::Code.red + "Hello" + ANSI::Code.blue + "World" str.assert == "\e[31mHello\e[34mWorld" If a block is supplied to each method then yielded value will be wrapped in the ANSI code and clear code. str = ANSI::Code.red{ "Hello" } + ANSI::Code.blue{ "World" } str.assert == "\e[31mHello\e[0m\e[34mWorld\e[0m" More conveniently the ANSI::Code module extends ANSI itself. str = ANSI.red + "Hello" + ANSI.blue + "World" str.assert == "\e[31mHello\e[34mWorld" str = ANSI.red{ "Hello" } + ANSI.blue{ "World" } str.assert == "\e[31mHello\e[0m\e[34mWorld\e[0m" ANSI also supports XTerm 256 color mode using red, blue and green values with the `#rgb` method. str = ANSI::Code.rgb(0, 255, 0) str.assert == "\e[38;5;46m" Or using CSS style hex codes as well. str = ANSI::Code.rgb("#00FF00") str.assert == "\e[38;5;46m" Both of these methods can take blocks to wrap text in the color and clear codes. str = ANSI::Code.rgb("#00FF00"){ "Hello" } str.assert == "\e[38;5;46mHello\e[0m" In the appropriate context the ANSI::Code module can also be included, making its methods directly accessible. include ANSI::Code str = red + "Hello" + blue + "World" str.assert == "\e[31mHello\e[34mWorld" str = red{ "Hello" } + blue{ "World" } str.assert == "\e[31mHello\e[0m\e[34mWorld\e[0m" Along with the single font colors, the library include background colors. str = on_red + "Hello" str.assert == "\e[41mHello" As well as combined color methods. str = white_on_red + "Hello" str.assert == "\e[37m\e[41mHello" The ANSI::Code module supports most standard ANSI codes, though not all platforms support every code, so YMMV. rubyworks-ansi-291cecc/demo/02_core.md000066400000000000000000000004761516262404200177140ustar00rootroot00000000000000# String Extensions In addition the library offers an extension to String class called #ansi, which allows some of the ANSI::Code methods to be called in a more object-oriented fashion. require 'ansi/core' str = "Hello".ansi(:red) + "World".ansi(:blue) str.assert == "\e[31mHello\e[0m\e[34mWorld\e[0m" rubyworks-ansi-291cecc/demo/03_logger.md000066400000000000000000000007641516262404200202440ustar00rootroot00000000000000# ANSI::Logger Require the ANSI::Logger library. require 'ansi/logger' Create a new ANSI::Logger log = ANSI::Logger.new(STDOUT) Info logging appears normal. log.info{"Info logs are green.\n"} Warn logging appears yellow. log.warn{"Warn logs are yellow.\n"} Debug logging appears cyan. log.debug{"Debug logs are cyan.\n"} Error logging appears red. log.error{"Error logs are red.\n"} Fatal logging appears bright red. log.fatal{"Fatal logs are bold red!\n"} rubyworks-ansi-291cecc/demo/04_progressbar.md000066400000000000000000000030611516262404200213100ustar00rootroot00000000000000# ANSI::Progressbar Pretty progress bars are easy to construct. require 'ansi/progressbar' pbar = ANSI::Progressbar.new("Test Bar", 100) Running the bar simply requires calling the #inc method during a loop and calling `#finish` when done. 100.times do |i| sleep 0.01 pbar.inc end pbar.finish We will use this same rountine in all the examples below, so lets make a quick macro for it. Notice we have to use `#reset` first before reusing the same progress bar. def run(pbar) pbar.reset 100.times do |i| sleep 0.01 pbar.inc end pbar.finish puts end The progress bar can be stylized in almost any way. The `#format` setter provides control over the parts that appear on the line. For example, by default the format is: pbar.format("%-14s %3d%% %s %s", :title, :percentage, :bar, :stat) So lets vary it up to demonstrate the case. pbar.format("%-14s %3d%% %s %s", :title, :percentage, :stat, :bar) run(pbar) The progress bar has an extra build in format intended for use with file downloads called `#transer_mode`. pbar.transfer_mode run(pbar) Calling this methods is the same as calling: pbar.format("%-14s %3d%% %s %s",:title, :percentage, :bar, :stat_for_file_transfer) run(pbar) The `#style` setter allows each part of the line be modified with ANSI codes. And the `#bar_mark` writer can be used to change the character used to make the bar. pbar.standard_mode pbar.style(:title => [:red], :bar=>[:blue]) pbar.bar_mark = "=" run(pbar) rubyworks-ansi-291cecc/demo/05_mixin.md000066400000000000000000000015311516262404200201040ustar00rootroot00000000000000# ANSI::Mixin The ANSI::Mixin module is design for including into String-like classes. It will support any class that defines a #to_s method. require 'ansi/mixin' In this demonstration we will simply include it in the core String class. class ::String include ANSI::Mixin end Now all strings will have access to ANSI's style and color codes via simple method calls. "roses".red.assert == "\e[31mroses\e[0m" "violets".blue.assert == "\e[34mviolets\e[0m" "sugar".italic.assert == "\e[3msugar\e[0m" The method can be combined, of course. "you".italic.bold.assert == "\e[1m\e[3myou\e[0m\e[0m" The mixin also supports background methods. "envy".on_green.assert == "\e[42menvy\e[0m" And it also supports the combined foreground-on-background methods. "b&w".white_on_black.assert == "\e[37m\e[40mb&w\e[0m" rubyworks-ansi-291cecc/demo/06_string.md000066400000000000000000000030761516262404200202750ustar00rootroot00000000000000# ANSI::String The ANSI::String class is a very sophisticated implementation of Ruby's standard String class, but one that can handle ANSI codes seamlessly. require 'ansi/string' flower1 = ANSI::String.new("Roses") flower2 = ANSI::String.new("Violets") Like any other string. flower1.to_s.assert == "Roses" flower2.to_s.assert == "Violets" Bet now we can add color. flower1.red! flower2.blue! flower1.to_s.assert == "\e[31mRoses\e[0m" flower2.to_s.assert == "\e[34mViolets\e[0m" Despite that the string representation now contains ANSI codes, we can still manipulate the string in much the same way that we manipulate an ordinary string. flower1.size.assert == 5 flower2.size.assert == 7 Like ordinary strings we can concatenate the two strings flowers = flower1 + ' ' + flower2 flowers.to_s.assert == "\e[31mRoses\e[0m \e[34mViolets\e[0m" flowers.size.assert == 13 Standard case conversion such as #upcase and #downcase work. flower1.upcase.to_s.assert == "\e[31mROSES\e[0m" flower1.downcase.to_s.assert == "\e[31mroses\e[0m" Some of the most difficult methods to re-implement were the substitution methods such as #sub and #gsub. They are still somewhat more limited than the original string methods, but their primary functionality should work. flower1.gsub('s', 'z').to_s.assert == "\e[31mRozez\e[0m" There are still a number of methods that need implementation. ANSI::String is currently a very partial implementation. But as you can see from the methods it does currently support, is it already useful. rubyworks-ansi-291cecc/demo/07_columns.md000066400000000000000000000035661516262404200204540ustar00rootroot00000000000000# ANSI::Columns The +Columns+ class makes it easy to create nice looking text columns, sorted from top to bottom, right to left (as opposed to the other way around). require 'ansi/columns' list = %w{a b c d e f g h i j k l} columns = ANSI::Columns.new(list) columns.to_s(4) The output will be: a d g j b e h k c f i l Besides an array of elements, Columns.new can take a string in which the elements are divided by newlines characters. The default column size can also be given to the initializer. list = "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl" columns = ANSI::Columns.new(list, :columns=>6) columns.to_s The output will be: a c e g i k b d f h j l If the column count is +nil+, then the number of columns will be calculated as a best fit for the current terminal window. ## Padding Columns can adjust the padding between cells. list = %w{a b c d e f g h i j k l} columns = ANSI::Columns.new(list, :padding=>2) columns.to_s(4) The output will be: a d g j b e h k c f i l ## Alignment Columns can also be aligned either left or right. list = %w{xx xx xx yy y yy z zz z} columns = ANSI::Columns.new(list, :align=>:right) columns.to_s(3) The output will be: xx yy z xx y zz xx yy z ## Format Lastly, columns can be augmented with ANSI codes. This is done through a formatting block. The block can take up to three parameters, the cell content, the column and row numbers, or the cell and the column and row numbers. list = %w{a b c d e f g h i j k l} columns = ANSI::Columns.new(list){ |c,r| r % 2 == 0 ? :red : :blue } out = columns.to_s(4) out.assert == ( "\e[31ma \e[0m\e[31md \e[0m\e[31mg \e[0m\e[31mj \e[0m\n" + "\e[34mb \e[0m\e[34me \e[0m\e[34mh \e[0m\e[34mk \e[0m\n" + "\e[31mc \e[0m\e[31mf \e[0m\e[31mi \e[0m\e[31ml \e[0m\n" ) rubyworks-ansi-291cecc/demo/08_table.md000066400000000000000000000007031516262404200200520ustar00rootroot00000000000000# ANSI::Table The ANSI::Table class can be used to output tabular data with nicely formated ASCII cell borders. require 'ansi/table' The constructor takes an 2-dimensional array. data = [ [ 10, 20, 30 ], [ 20, 10, 20 ], [ 50, 40, 20 ] ] table = ANSI::Table.new(data) table.to_s The output will be: +----+----+----+ | 10 | 20 | 30 | | 20 | 10 | 20 | | 50 | 40 | 20 | +----+----+----+ rubyworks-ansi-291cecc/demo/09_diff.md000066400000000000000000000015641516262404200177020ustar00rootroot00000000000000# ANSI::Diff require 'ansi/diff' a = 'abcYefg' b = 'abcXefg' diff = ANSI::Diff.new(a,b) diff.to_s.assert == "\e[31mabc\e[0m\e[33mYefg\e[0m\n\e[31mabc\e[0mXefg" Try another. a = 'abc' b = 'abcdef' diff = ANSI::Diff.new(a,b) diff.to_s.assert == "\e[31mabc\e[0m\n\e[31mabc\e[0mdef" And another. a = 'abcXXXghi' b = 'abcdefghi' diff = ANSI::Diff.new(a,b) diff.to_s.assert == "\e[31mabc\e[0m\e[33mXXXghi\e[0m\n\e[31mabc\e[0mdefghi" And another. a = 'abcXXXdefghi' b = 'abcdefghi' diff = ANSI::Diff.new(a,b) diff.to_s.assert == "\e[31mabc\e[0m\e[33mXXX\e[0m\e[35mdefghi\e[0m\n\e[31mabc\e[0m\e[35mdefghi\e[0m" Comparison that is mostly different. a = 'abcpppz123' b = 'abcxyzzz43' diff = ANSI::Diff.new(a,b) diff.to_s.assert == "\e[31mabc\e[0m\e[33mpppz123\e[0m\n\e[31mabc\e[0mxyzzz43" rubyworks-ansi-291cecc/demo/10_bbcode.md000066400000000000000000000012511516262404200201710ustar00rootroot00000000000000# ANSI::BBCode The BBCode module provides methods for converting between BBCodes, basic HTML and ANSI codes. require 'ansi/bbcode' BBCodes are color and style codes in square brackets, quite popular with on line forums. bbcode = "this is [COLOR=red]red[/COLOR], this is [B]bold[/B]" We can convert this to ANSI code simply enough: ansi = ANSI::BBCode.bbcode_to_ansi(bbcode) ansi.assert == "this is \e[0;31mred\e[0m, this is \e[1mbold\e[0m\n" In addition the BBCode module supports conversion to simple HTML. html = ANSI::BBCode.bbcode_to_html(bbcode) html.assert == "this is red, this is bold
\n" rubyworks-ansi-291cecc/demo/11_terminal.md000066400000000000000000000002511516262404200205660ustar00rootroot00000000000000# ANSI::Terminal We should be able to get the terminal width via the `terminal_width` method. width = ANSI::Terminal.terminal_width Integer.assert === width rubyworks-ansi-291cecc/demo/applique/000077500000000000000000000000001516262404200177525ustar00rootroot00000000000000rubyworks-ansi-291cecc/demo/applique/ae.rb000066400000000000000000000000151516262404200206600ustar00rootroot00000000000000require 'ae' rubyworks-ansi-291cecc/demo/applique/output.rb000066400000000000000000000001521516262404200216350ustar00rootroot00000000000000When "output will be" do |text| # how to get result of last block? @_.strip.assert == text.strip end rubyworks-ansi-291cecc/docs/000077500000000000000000000000001516262404200161365ustar00rootroot00000000000000rubyworks-ansi-291cecc/docs/assets/000077500000000000000000000000001516262404200174405ustar00rootroot00000000000000rubyworks-ansi-291cecc/docs/assets/images/000077500000000000000000000000001516262404200207055ustar00rootroot00000000000000rubyworks-ansi-291cecc/docs/assets/images/book.png000066400000000000000000000323111516262404200223450ustar00rootroot00000000000000PNG  IHDR\rfbKGD pHYs  tIME ߓ%. IDATx}y|Ty93Y d-RVŶh{+uTؽ׫ϥ_-޶TZ+ [؊ (B mry3$d&IfyI2s{>ϻi O\<1x8\ `P(!`Ph664As4I5dǠh$M$ri>gPEeF TTd)ѿG.m Hfpq&IC+76G!f a Q;U&E Ku0=n'1گSG1`vtu@Bku"x0iYj/}+76St~<(CldP$Iމr"E@CHeӊ}ERr"Dh~ PtyaE ;ݎ[T#gRȐyQ`[a0_f5]rc"KU0i!dP<=$x"$hN 9Z8&=Emj="Jr8Y4 f0#b]e" !rdF"|A'"!J"Ak#KPr = -h^~}LZNDCɊBhQ>F'Ahw`:8!(\і^(0<| ,5 P9fo "}DWm$ ĠSV' &%Me^>E9}%JF 0A9P̀[PP!zH/H7y0i1d3wQ 2u?SےA)nu.;px yսPrFGz@ö^K 301F}=b߉G:1b n`Q`4aL)Yʕ\dsB}KeX/WA~VZAXut/Yꏕ+7HJ8|;YjNgG"ʰG(E žKt0Գ2r e/d J|O N(Qj"ųwäO(JID{xĠ!mϓ}"iGq{LTLH.N} ߅nv.7PʕOdKwƝdR5@U$@'!Y'KQRj(ƣVȪ8᱋g)"{^d'{jpAGF L @F/Ȭ_~M*RAw^ӧ-L?`1.+zG k<&xs¤ǀb;JD=^SL ";^&K}̞Z0ɥyw 5 C3F!~>SB `{~JYʍ"ICQKu?ҧZb-d*}@ 5\UKJt'` B~On P8{U6^ 5-pnq&}Qy RfvSF~ BJAخ̺сnsRr)Ա3֏樼2ݸ~v?N I bnӂ@Kp"opjbE$,wm~p ű/lk;|jE߽*P" mbDD_Hp1HAy 0sh6׸']4%HnqI+۫-`_H? b0BJ F \cM:VLiH > Vj{#v1H铱 qD pl=k|rJL*5< Br~_fBÊèY 26j(\Uj.ēߒFk?HQ_BЫ FlPjs""p1 CK9Cmttw0vIE:G(񙝖b\R[3z?iH ?W9fb.[51?!_yD8 2 *\x՗]9ʝ"}'B*WkT)OB4H䏩CzL"`?VtDʭā O.%nqL$~!}NF3aVq?\S͌%oqmݓK$uv?Wȟa 7Q>;'U`.]]NT)ffʩx ߡrLN|ҧT g7PUC9huW7q='"w&X;c$ tWo: ]ʉv*"7?#+!q]]]ʉ 2:`o yT n=?BAr#fjt'y"pkWog<3p޻_/HgIqnv31HLI#"OL_/H!C(v$OT]?xk%xz+L*5 W/| Lv؀d*}iPVA"HB~AZASaѷ(JOOxY!8mL+XIsLx✌|P]-O 2A:[\<`J]([W~  Vp8g`(u DY30[F'Ǡ UF4 `LeyB~`N# ’UdI]2c0iQ8S/ fÀP=`4 r&3ä9SV!R/H1zΑ0i([W~#Y:W0}Z/Di&Pj׀ K}l]i]([W>V4 ޵zK i\~EA\TjsN%N({tIBy?=Lu><R cX *({|.46VV'(!@ҁ.Ã8r̎&-nӞwe.)ƃ0*xxzlt]"BՃ&]R)߄!W/dRK·LYئ"/ItN)nvpaժSN]bדfEIhmAv D_3s:@& {zYjyuJ ZC*TPv'O{M\`r<τ5.r&`5<ŘqHZc0nSݽxAsׄ_Ԁ @#lUyAEnaN1PiGjAW8'[EL"|(g"əs'(2 {M`^HU6 ˟&CQ#8=&d`%@Xl=ˏj߇OsE 'X([sg`^٘3Sneor=A0]4G.e簭o QɭCtX3 3s&EBež7ulޏwOK`ŔqaqA,ʙdDD23`weOժͭIvy1.G? )ADs? g}]M3a?Ɏ_`aBi>V8 ̜P_>65D 8]^ɤ @#&C*}Y< <Ř)5.L~; l}L*Ē!sqِX?'P݊an#ZIXEsR`HXdbN4ɝ^cxa'T}w;Nˆ,'\yyg C  s _"[CKO.J1ˆ+W8o؆OGޮN麁Uc.?-Y= Bd{k<3;֕e*4l՛4/ѿ@}-эkRz ̚27$|y*'>')7zr!Nf!Uoiz Yʔp1;w fNmcngAXj%X5P`\:0 m@LвuY(rV {[}'؁9>m >\QTu> . M'Uo>אAEEI9ཱ5-Ѝv?gJo%C.>Q   j.b~Sr o;ɒM;<Ÿ;xqCATGL Y(S=^W4A,5G)2X_ppT%_:Vy\3R!}W. XE6K7IX ݐIYatLN؅oC 1r q:s(4!cѓxp͖{!+m}Soz#,o'_YFR+]=`̌b<}/p׸B@r",ro 5T嘁z߲H(PysDQM\S)`(TrL/O&~=TR3%:͝MS~evlT'.3z,2Rfl@b}҇O0 .?uQhcmmX`&= ? ͝. i@W. r9t{!P9crˍd@v c Hs(&zƣF`92c|sԵf"n'qҩ#O֭1Ǜk䴟`fΤv=Upz9 v5lSSo)[4QhaIbL33ga9,Ȕnqm{m58BUQW(|Gi5]o?1m 5uٸť䌽w>vS cq AQ D#8nf<5\?~_x!i@j#g; |`EW-^ HKDn :ZtO 2o .V3=ΗFO0at.i(Bz01EC g>lj@& 8yzAVb0BT_ ,W1 d @- j 0^ E t&{hpvq8 @NA *im{PEDE=2G HS@=HAi) +b =B{ERQg @^oȋ郤'@DA#%d%r@(@TLٽAz!6*@:ʪ? ;u!AvVڤD* d%Zfi +Ѭ';d@00=M @C// ^0sE%OcuP p@77:AV: PntGtADo>@xJZ&7 NJh(24@} (Ǥ)1 Y?Pj˟E0T$tu kTMNB3ǫov2!HU@ \бqb@ZuMiA fA{Sh G-Ar~:0p(A E8plKA;`(/nmDX@A8XŭM)@{Q "Lr Q.:r_\@0> m] +_ |'@MqA8W]n}]m eED+Aq!]}1$}2cRlép;`W/2O@nwshŐ:@F`׫o奛V r$"v&M|=-3jet_ci7Yak{ ]>b(P^x!DYǮ.a!Bl "xݽ Fd@/9S}lrWO;#G ۯ;姢;4 :@E @ |LGTmDUQWᠿ'naH33)2LN̜0[(FACGݺ'}7WudƮܽPd`vΝ~TG;ðDsJG? g{'3#͡'n]뱍{ /@fK(/{'`w.}li|[^ʓp`s"ɟ%c^٘"@ /Y|7W,Yh=4IXeaLC.Ojāe.Լ[ ]'B̡XX0^䟍Rk8抓}w<ĮB k @Q`A9m̍?;[nZߪL1,0uT\QTK 3:sr$#?h5 hƬgگ}`I1p0ptɇ t4?stNO+>'9}iPo\a]0?"19Bzpnt;'?oui!p/.r>z <#6V/F ?컹84E¢zDqqaVdʙ|'Oxkja9S+pEc'39n1u,/8Rv3и!!1/l;\wqԽ~l-S>GtyH }M??[]q$al&̄Y$aaaG>cػw/XG͝=T푀϶v<B=%kmI@A`QW8xխЭN>s䇋q! a)!R-{.Aˮ^>$HW a .W;ڇ}¯?;W_v .@R!{_{J 9s#kϧ &{K'Q7S(lqwsjDW/P O Ho~kX G#w<C'E@{AR#~8Px.~: msĤ_H7 @]^qAJDPcߨnhp %=ANƍ*< pxOsjǤ ;Q^xɂ @A ~[[!^4 /Ac*"EF`lx\7 aYՄw`[khڋ}v1mɞߦ.WC|'RBu&MR`bX\p.>Z0geC8475a4e>unx8Hy=LZT EC~4\QTϘ]r[M{\llG`k3;s$&-e *TƫP<{">U*eiuͺ6`W嫰k%зbYxE߇(JϞ xJiߩ`]YGGVWܕо(Md97 E cgŗF\EsRbFc}+>Ѣh/ä%+SZ"0FT!LJh* "ЁQ+qKlmzxp!4U䁅߇I@T.B"0GS3.WF^¡T?>{ԿzLb;&~[dw`}&z'~nN F:i[R}7W4E`:dШD ,<|g*FZOmU '\[]q0Yt#" &W}:j v۝ywиL^FϒҎ՚[vaoH6p%(J$ш1=dg-_r֟p+t DlvM:{Rh-]0i.Y*@YcqO= IX]Cppx,ouEfɮ^oIRfBd ef^ ERbЇA*C\$5 } 4W%&4V) G{"|`^-IjnQ-G ҄v;(szڛ ($=>8Cͯ ֓vVW4J/&w0ypCl(GlhYRAz:<3&h`L;Wz/ tCճEӡ۾i&,=?@;[ 7lI{P`B>z*px&(Pn"a@a9&LouE<=ArS0<PE & @+fMP &p jjn!Crix^jIENDB`rubyworks-ansi-291cecc/docs/assets/images/color_bars.gif000066400000000000000000000323211516262404200235220ustar00rootroot00000000000000GIF89a>Y&&&:~,H*\ȰÇ:Hŋ3jȱǏ Cr4@ɓ(S\ɲ˗0ctY͛8sɳϟ@ 곁ѣH*]ʴӧPJJ)Xjʵׯ`ÊK,XhӪ]˶۷pʝKݵ˷߃" La3+^̸cD#KLeU3k̹fCMiwS^ͺkc˞M;۸s_Nq+_μУK7ν{Ë󾏫_~x'N߯ڻ&4ހz& K5<'6u߅fvaZ(whx "b{(|h}u#_')a+ido/&e36g7F)i;Viej?fCCv%HG)LKiPOTS&YW)[[iA_EcgJg*hNkjRo&Vs6蝐ڹzi韃f*衜觊:*j%vybjj&9;눩z"/j쌵&{#z*mV >x*m͆v7Y.zٶk/vK+qKw¯0Fl#9Ŗ1 wl {Il`,O˛y,h!l8Ct!L-=DS5e٬\97Pw/ mOEg \n9-6BQht;i6S]t5wEi}ۀHmxVu'{7.9nyu/w{CSNcNws}胓n`>flrb^hnKQ#OW3]CMSScoYsϵ6_G4M!w2L-# 83L#c2L/,0 >L`<1nL#L0FLc\1vLl/L|0 K""/$ Lc"œ(.(K⺬.,KbH.0K"c/4Kb#8-8ZK٢#-<2K⣴X-@bK" +DJbdI,HKʢ,+LJ7M8b<(cF!9jL"I|b9J\r'E39ll^\&9|skEh!zэ7']czᜎ8K=oTկh}\ ԇ]c'Imr+ko@>}Qv{/y?< o;)>_߼+x^}nz;=wK]_[O~gO_Z}o|w>~ث_מo>ҟ|/_T>ֽvG>ӕqS_֧}~g~~F~J~\~6'>G gۇݧ  ,(H8gƝ J&NF`f:۩Bƞ )Jj0 ʟ<@R&,Fi4ɠ *"F#j%.2ơD*&Fe9ʢ;?*AJ f$6ƣ/%JjUWƤ[] &F(fK ƥ5 7*qJsjwyʦ&EgjȥQʧS꧍ *EjŨ *Eemoʩ*Je셪Ū%JjŊǪū %EeʅŬ嬥 *Jj窭ʭ%Ejąʮ *Eků寮*Ee݊ߪ˰밤+!Keƥű뱨t%Jj57Ų;= %Ee+ųf +QKSkWY˴崘%EGkX1˵3m o+zEskuŶvc+~EJeMO˷l+Kxe|hŸp<%iKkk^Ź빭 j%nEeZbź.庅 +KkPǫ˻\`r%LEkT ˼ +BEk勽NRŽd>+FEe˾4+L@eDV0ſ8%Kk& 2%6EHe" * +1L3l79$(:%E'lM O, ESlU,C,Ed-/iko,qLe _$ILKlDžLJNjǍ $De{Ⱦe g,ɡLɣlɧɩ%Dʗlʰʁʃʽ ˿,DlŌޤ̳,D̢d̝̟,LdԄΔ$ιLλlζ $DdϲϺφ ,MmШди$ѤDmѬx- /-ҚD3m5ҦҪҼҖ#-ӞDjd IKӌO-QMԘdԜԮԈ?Ԑ\$)M+meg~km ֊$֎D֠dz[ւNE G-ׁM׃mpׇ׉|׀ؒ$lDwmt@ac؝ ٟ-bD٣m٥nrل^ړ-fD2d}ڹڻTۿ-M`ddvPۯX$$ܙMܛmՍ׭F R$VDhdB˭Jݵ ޷-Mm8DHZ$4Dm< .*Dn6:L&..Dc)+/.1N(d,> # N nEGKM$D0d ;%'.aNcngi "$CWnУAC}.Cn煎s.Cc]_.Nc#yN{n굎귮#Cc҃뫮.Nnȃ׮#Cñ혣.Cnƣ.CCcΣ#Cc/z{'|'}.?0_24_|/|1}3}579;~=?_~A~CE߄G?IK߀MO?QSUWY[߁]_?a_ce_g_ikmoqsuw_y{}ߋ?߆߇?߈?____ߒ?ߍߎ?ßǟɟߏ?_ӿ__ٟۿ_뿙ߙ $XA .dC$NXE5nG$YI)UdK1Y:YM9uOA4PQI.eSQN}ZUYnWaŎ%Yiծe[qΥ[.DyaH&\Lĉ/fPȑ%O\9'U̙5oyiYСE&]z]ԩUfݚ_رekmܹ7:o'^|gɕ/ls˺^uo]w'_O2O@qRsPBrPDsQFײQH>+3PL-tBFCeRRT-UL[%SXtV6ERsU^ \W]XeVdmuYuu6^ XjZՖdŐYp;|v\57j5[vpՏ\|;w_v.^U|_w#3~aK[+Kbxe4vyc dU-My{e|y5e6͚g|h:zk:Îj ǬVkOzĶF{&G*n±V\#|r qWq;)1G\9A[I'Q[YGaw[ivqYyW[xZyyZ7zZ{{gZ'ZW}XhfS&@ek1_DW&AQ0fE}qb5&Žd&t ϥ‰b. 9&ÏѰa64C`>D&|QZFD1`NT%hQQ]Vlyq^^${%t]f|zq\n%Glq[vågU~ %Hm["S1X$%dQY&'_qRX,(%e2W*WJW2V,o%RRO.[KXrV0I%L<29O1STΌ4$JQ6PqQ&8/%NMP<':G:R<)O5T\> 4@%CB01D$Q9QMFYWqM(Hq%R,&-JS&V.Lc*SH6UNS)>P*T"5IF)R*1NT%UbQUFV*VUq^EX*VUYfZӪV5Enm\c$ѵv^WE~+`3$Xbl1vB},d%P=f3qB,h#ZAmj%ղvC-lu#Eno;-p%\w>=.r2D-t+]P^ֽ.vpMx#^ zӫ^ష5|#_;~߁w9/&0>03:~0c# S7& s:~#=&b6.~1+&c36Cx<>n $Ff %3y1N2a&eP5VN2O-sy2^ ,Րdf>35Y3n ,gйv#=94~s&Ά 3E35~4y&PҖ AMs"4C-jԦ& ꇰ#~5"Z, skg "l[. l0"Pi֎q*&#>7yu+~7$o{&7+}-)"¹3! S"qQWۢsl&&rг"tG F? t1(N:'PW:Mu__;>&g7JվqF{V{v| }W|+7Gc<1_xO>|3xs۾yw=q{oO󽷽q{~7>^/?~w}3/;[_ק>O>}WO{#~_ @@,@<@|@@l@|@@ < @ @ D@@@@ A,A@ t< 0CB?4CLA\D,4DGDĹH FD(DLTITMK#DQNRPL$EVStW|UtE[X\S?S@ TATB-TCSBXTFmTG}THTITKTLTMTNT SP UQUR-RSTMUU]UVmV=TXUYUZU[MT!T]U^eTJT` VaO5Uc=VdMVeRWmVg}Vh:UjVkVlS\^VoU!VqWOee=WtMWuRimWw}WxUlWzW{moW^Ura-uX-QWMX}{mX}ZWTXT5XX҅ YYyX=YETmF،Yb5׏Y-XY]ؔY5ٕeYuYY؛MZ=֝mZ֟Zנ%p5ZM]ZZ0}ZUZ=[Zږ-ڭخ[[1%[[7E[AU[dۊu۷%׸[å[M\5Sm\SAX\q-\]\M\Ǎ\\~\V\յm]][]AW=]`M]u]u ީ]o]X]}ޜ^Y=AVM^Ms^ ߓ^n^T^ex%_uX-AU]_Km߃_n-z_~Z `F`h5` VAm``R aW`  afWT=aTn`}b)a">CaaaT b!.b*~S$Ub dbHmb)*5b3S-b.vT/^0&c9>3=M \c6v'7cAS;.;c >.WdHAcC6dD@El}HIJ.KL^6N?d eJ:._Sf%bcd6ev`fdN_Of)f*f,Mf?fobp.bqbrf@sAtNG^g8ng"~g$gUg|c}a~>b>@Avd,0>hNh^hl|h%h`&ah&@A{h1i .infmFghfiu闆 <Lin^ia`i@Aԛ.=jNj ^jsꨖjꪶjl|jhn^_k?fAfݶ߷߸k秶ؼ&߾^V^F޿V&~ʶvϖֿ>̎fF6٦vv߆n\nn}؍mf\]dg\to.=oEN]o^V\ܖnooǕo=ﭵoOV\o\_cZop}pp Fm ?\ [ 7 S-=qpmnq`[qqMq&^5m"X#?r$^od0rUfr-R.^/Z0_a1X2/.=Ms5F~s8R9Y:56X=,s tturC_WD^EYF_GBtIttt…tNGWOYPu;pxUxW|\}a-lxNvWVyVg[Oy/]hmwFx7yaV`tWey- zzk}yEy7UwV夯zz[\azgV{O['vf_Yo{V}n`/[{Ns'—UZg|o~|ȏl{{?|͇?Gҏo[ϯoз֧7}_77޷߷'g_/or~+,>|+O^}N@1~We7,h „ 2l!Ĉ*h"ƌ7r#Ȑ"G,ʔ*Wl%̘2gҬi&Μ.'РB, 3ҤJ2m)SRRZ֬Zr+ذbǒ-k,Zײm-\&ҭk.޼Voѡ 'Ċ/=㴒'Sl帚7sbТG.2ԪW,a.ӮU6.17p/nʗ3?9-aS',쵯sG;/o׳= f 8 ȵw j FEN9x!Nj!!)8"bx",E}T1!5"9~V"=&'#a/$6*dp::[>J9]HZ ߐi$W$aV%e:D%i%eIߖ\&by'YfgAjgFt *ۛ)gv^'n'z:韊Z Yv(F:*)urʘ:ښ㩹+T +w~+$lNPA+ݱҨ,6-׊;Q[-vnyʻNWuҡko Lܼ//ҖjK wf0ƥAlƒR61ɿY|r\v, #2d%ی92v,D+?v3Ҕ鼴D=;m]D[_Ik]4!aMA,~mv^Pq{6eu6t6`Ar ީnUߍs8 >E{zOk9U{USN9b.!tV'VT{:O9_z-i;W+|N </,7)7;wWJ_Mu_|g܏ /2]v@V?l?%V5E oSZ\ /,#ʈkd(08L9jxGMM֜0t݇Ǟ0x~ai?Py |X> pq IYm/:.=Gw‡)|O&^ 838Ϻ,ZS䀗/uqjT [LL&,`aS8(l` K$J.ieRaXK'as$&$%8(kLH0tİXOa+w(2iع!Jjb!M9MbQV nd\Q`=!7Wq'ֆ84ɡ;HK j`ω;+E[!(Ӡa/]ʨ Z bYvPcSɀ*]i㛡cؓWNI^I J${تsB޿"f()a00@)Ta7g \0 "a$irHnS׆7fv8vQ*.K7<IENDB`rubyworks-ansi-291cecc/docs/assets/images/gears.png000066400000000000000000000252361516262404200225240ustar00rootroot00000000000000PNG  IHDR\rfbKGD pHYs B(xtIME" IDATxyxUևꄰ$ЅΨAD Wpw@]QGeFaPGDAqPaDYY%,EH J :yҕ[so{B] -4uS>ɧȳ>^XlѕHB좉ČkX"?sP%BuhA|䮉:MOzݧB`|.S֧)y,Z !F7 HuiS_su[+!O+R",3 +Ni1X}57p+p9 b`|I] |$Yf0OW> Z1~K7Y"ae+0+zi1H&p%v"a|+^i1EB^Е'i1p0 E+ǁ)pBm@/@ 0xNWebRKݤ5bٖ|-M!{X¿DZ#2/)J~WeF\xLWbZv]`<+.1w ?x.zp%h]G1Xܧ+b1~*0 y'GʷO /$օ2< -wl-Xs ,bH2;@cw@-]Vp2~-.@!&FbL2(9?k%N Sv]D^!e+p|"#| xxHx"1"191i]Mk`V{,q'D^)jLt ̽!KKc -fy'y'Dut 'F oZ8#;֖b<+vB{B|nŰ@sNe%!F LbY ʂ+:-喣%n8~]ƈ"O~!N)\R9'}~!)Iw~ʷ`y/1艰bN n60Ҁ Z2Wp/:OfX*| |hi#3GJ>p:},mT(*5ROJpiE0JwD BYl._%JXȦVDaX{} T*ssҘ5kdAJB@pJ.;"~APZ`} JKK0V2 I L!FWQXLjTwx~X<3B$c1U8]ہB$>d5|Ir ,I xvwZv*%a-y)ڨ{rY=Cx\zȜ ?/ZΗ1V&4ѕo_f#EB ^ ơYLЇ /?XLZ&rު5^'|M;`d -;P8@ljT}ciwQgC/ 4n@X?@kK.a-k^ԝ6xhޠTв/KX σuG ;ap8|_WT OcFԪsBӾI`hmnBP0)z奏eY { O!hNoT  ٶxka5Cn0eGQfF<צr oh2aj?!T5LIdՉ˦4} `hbHv*!=[NAxB|E}(EC~ L{R:E>8֣=<ۥ1sIxP=a?5}]筓3G7K`,.¬ЕoS"~:i7]W#W'1'USef5ʄYYЪa? ʖɟS`HЁ`K6Ï[avmhlH&Y})U *Z0#rדAezuBk :.j|"?:m_s߿`1})*tha~N;EkȝМ0&"]3 T:7̵n,Q*q˟BBl; X:V­|ON"8kv@2ugw LRW5:Ԅnmb)ծ,u(~jDMæ'yG5P݄ʋˀ,Ck1+W"S%~hy+|v+DKbiy.kS*߇;CiKs3dzz&}xzJ_2W$h ,&]i7SJ\Ɩ֬dsMiO6}g瀏A _` ~ָ^?tmҾ|궖H$MStj%7tոp< @8*̑ hU_m*'mת9R `/1ԢS-;VvsI ߨ|7ζEI_0/UJd/hEia=-1IEoռAJo nYͭC n-@oT'])/Gb`jAOm-OBz꭛bKK{d>oh?MBkܔMx *8d"rMȇI}yȾ23Zvs`k_چAo^YcOAGR@8t5a6ZR%ӑC9ѨRAW- =չsϸ޾ಹVaxҿˬETc` ]Q t3LҺ 3;vvW"yTh2P5cUZc Y6~A۔杰' z 0DWQ4Oq-*t|HUy\˄ltkӕyDaݯuʬrk$!Zvf;!)@3]We{\ 5[!&\v9X۶E|f>*y:l[;=? MW B`y<S_>DġPM[R? kR [@jU/Ensu[qRW;Ljη6laদyMssи -ENqI+j{{r"fEnk%e'h?3}B{l}' z:YZ?#h VE`xQoE)_|hoZns)0niއDġQ6Gu( )^C}>ϖq)vڊ_4-~.T˦9I3O}O?'IMV.nM\oF6TmpPՐnfn`]#~!ә<-F1'j\/m[4,0)~~KX2&eewpϫ~#smz.(I\xa hvT؃sv||Tp_]a t $;_ {I|#\CB?iF!p部U(E={vP*EP_C6HMP--mNPgu';X.eDžI9ը7WA"Μ~G0m0;TV?\if{_*n7}XR҇ Q7a?uW}80Բ 8Ix?f?ø繀_v7ݯ`5܏gii]/LsI~ɇ 9ݷuσo;ܛZT"{J72JEeÓ9fj|4Ho=FWs~C_ÿ#F'ߜ6l%@gV-R3(q%Ƙ)"~I2:XK=vK7؃qh?(Տ[Z iD`לKaed65U'֭RGԡCKN,";؃F-yIsP?u^2Lg5ոUmPx *SQ}T o1kzzxw?LA+I{A\o2gjkl+:p`! K$Ίx{vF艍>N]{V!О~?jLRَ~a:\}qjXm",B4m߁!q!hGvc±iZT"%wfh4C̈.wͲSᚦo;;oHJ]DjQĕP5:'ύv`vdى}1f^Qyj9~:JLG}%& %@lϕbdb>mbt{$h P,, OEi.^8<1FO{$hD _2Ee7$H l}쾗Dt&A$A l9F 2[41ӿkt6MG"Lb@Vy/T?1PW{A\ 6lwj3Ew\I[چduKwvB{=;vpVo}5jO{ Ck}V#T/UЖ5гx|,Tv{=9`nYofC2d$aQ0bamjg\V{#cOYK =Q멺w&<ѿ.>v|jۼ%WfL۳9VN[< &:ʕ>~a*ͩ]}dj^w^eZYfq17W[DJ7șm* @;g;@Cr1>B{_Z_gg ZzGxWuA|wh'g.7cH )gt fy*-dު9  ^X?VSlЮ{妐2(J2&֬6iD(v,fIU̬KZwS=rI@"oqza"@'uŎؓQ>@ҊirrѶžP^Z'VEd*5$|L#svYZ}婉ucȯДRZv {C,}BP3)wQGɫv8[W] Azf}sPSk#nwFE}ԍmi{)ujQ 2f hTtP0jǵ鿫 BtQQeʗ*צBA=mwg׬b?}N^PxR?/؞L"x,ߪ9>r(\MЁ8"#'-,4ԿDY 2 ksuݖP?n\q̕ ,7]q!ʪY;3܄GƋPhSW­wm32~aJS]aǓI{iksJ3bw,uc+i o(waӡY=/uhJfh HVПbIcl |V=@S ̴_`xq2ֱǤ*t>߬l[&Wdf83aZ"g[0y9>s3?)0a=LdNR-VüDMX(:o[$jL\x[UsuSa=a|%r?LWMou*p@9z#)v>>1w#>s>Ç}込Ρ"߆+WgK严 @W7T>yͣD҄?f6܅ʞx-n y.(;:h_[+KgZG("p0|wο-Z%,m.93&){XYB|ZN,K`JqcRDg\`=PRl϶PW Ȯ>"k7h£0%-U%U+]y| -{p[["wӜ9,lv=Q~S#:NkE-*9V/-3Cʽ4]JǕ7qsO5a̹9"M?l6tSoIUsun8@ IDATLЕOEu)p#f-dz[W=&Z:n\_ȹ{ }[utŶՆha;svXt -& B(F]Hu`zž< Ү ;At L ۼkunE}ݍB/cx B CWe ; v+7Q+Wu'!cˣ,Ek`Z # c+.nW_}Wcו.2RH _r|O(*wE rh+_@N.fp Q(~)ߖX<QM*ȟq)~ei|kBԢYC0VzQo` n'5EybwSsR1ԒO?5z^6!Ȫ}7|9&!sdKj3/`|;,/* 2B$@7ӷEBN˓I mBCoc ]s0 Xt侀hT'}TF7Zː*‚@](։>"Mp?l)4?A ]{(=C- +/@?QA@, ŦX&xB K;a%c*|*UdaہroLZZ! @W.Ap'ǀ-ėX&&YJd,L{-ŘniBAS1*@g||G\a ԰.|+߁Heu.q DmX8u݀%3-⏸X& IL.!i>6!J BG nد$Pn>qi | 8V#P Kqp+, C˾&%6(6&%'`@W EI!0GFIFX&Ԗb1/ L06,Dyb '3lVv\W$Q  4D FM&֧N]n`X,ӕOvr0*:#S~څhpJr'?y@)Wt")|lÀ]xIENDB`rubyworks-ansi-291cecc/docs/assets/images/girl.jpg000066400000000000000000003455431516262404200223620ustar00rootroot00000000000000JFIFGGC     C   zz f  !1A"Qaq2#B 3Rr$4bs%56CSt&8DTu7UVcvEFdeB!1AQ"2aq#3R4Bbr$CS񂒢s ?Ebpiu!ѧy]GbFI9V)7a FՂCOkKrTVP2T{LѩȊ~rM08_hu -V&п^0DKܤ]Y|OcWZyi%&_b V6ab hj>c̄70Jtӹ)M*ArAtD䗒HCj vcbNrkY^nV;%%[EAcƧӗ6=Jz[C2A'ɉ`p *ژYiR9IaS{pQ6bB$-1LO8ւm+RfoSL0(.{WB6㸌{Y/ 8Mc>)PckzQ]M?Fu/VI*)#+U r@g@HƸ/ḟtNC|*տ-]w-}}-,,j vbbNr[ 4wR(k51ԥ`x?xcH"b q S{ghmEpgQ]ZHH)b ?/L4x8ԟ ǫǧu3bsx7&=M}qi-Ʃo$&dr )5?_ڗ}M8~kjPiݿ 5Nj\8Es+p(~KNn LJ',<3G}Wkke+WV7\JP# y8'6jۗgS.bP?T}!O M,9e("bCtp@C^ Yků |l>zn4[Ԯai8W`T p +u﷡j#'KY &^ےOκ.4G ɁܓՒ=9⿮2dLJ1u־WNI WwaI`xԱ84'RP_g ^զN١y"+,r8%A a.x=̲ نo{4x)}#QiƐo<Kvo&v1ȠG ?"gHGN^OuR+ŕ"Ep 3ހeO5>#Qu4FYa<0 gvblcs@zmToK|{Cu^h=AzFqjWipmTu({1J;/6ֶ=azլ4r+ob.1=cn'9iJiSb^91v=PO u'T_u+mZ XDՒR世<`/NGX2LҚhi &TGw Ҁ'_en:Ǫttus$I&S-mm{=>~P/Q[}.0_5ˉ&C&q6s4w0}:;BF /.I]ȧޕIx ~€ªbm;[ I*FO 3X9F/ DbLB<?>Vvm3!,J2YFFڐ@|*BXV2i,} 3tRF n8u\K8eu3X"5ChlV7MmLeP۰T=5x,TR)^\[]^FצUXavUv"^19=SBYBiavYzJj[n1y[n#'B{|vFkhB_ٳ?w>>"O';_#Kaeߛn>dN xz֥W[(^nfU*{{r;p*9{~ggwjpQc ]~@ 6 y&Gc%P#x;4$@3/=FVMu#s.L=&u2]Ip/&7H$l@2INjΚ) $ \\Sb[DAS=Oax~.uu%%(Zh8a%#ZxѶpXy̬jjZpZVKNG>IcHM˥dRCp7p2ǥZ(KfMjVP5W)N2 #=XU% n:z#ID'an8f[Ws*b&>_RtdYŨ4Ÿ{q>b=Ogs"n:}=}u6ՙS4K r =VlT5ܓkxfҝ3Mkgc C!M[hy/*3QusrX/mghLnV ?2l'da_ST$}/U[訖wV~'N);nQh#?;* ߆R_WEyCE֯WiԖ"P88OqHpA;b_³2GjP @(P @(P @(@aUs1@qTAjSu 3$.h<7q+]koS K9c= .y4к̌P#+H1FI |ID򱃫z$3!q{:(}9&;.Wcv ?:qܚ$zsg_RJ{=8vQ(<)i'lʅ3ezOctmp#,>풭3hn= LhC@2pnI{1i59oз95~kVBJrѬ2J~s ?qMo4q;*ʽА@amc)7}Fk [4iu)x: ~SPO$^zwNIʹWYq> @>.Zu4㿞wDY%bvr9*J fad옚tfdP9 w~$ JSOWh7ןk iGkPTLmA<+%W^FX k} 6QSQoMgv*}kpI}⥄R(FPqMz'M:Nܘ{iyzn8ʾE=ˎ+%Io$ g?&I)[w,kF+<ⲓS;q"r>$WY7Mu$r[X #b>oJn )\kMDYʙݎ/LRrvc$ѭDӺCnm?0JN0 폕DLI9th|»c*<9LrDuHPېo4} ⤓ɔKPʬ RG{q1韏eq+̲@7]>%G"4&d^(#+ Nɼ  hbp);3.j- 9u7DVYo4Z3Yy!_wv_DOꃧz=i-罚X" p*j>ũZ+:=m~}N'K):Y6l//F1w_Hz^^u:?~].ƴ2θ_r7~ϻ.#Ŵo? tj} UƟIjB(d_tkVq<2GjP @(P ?_@rhhU?@}P @(8 *f(zɯuG}G[ӄ{7\p7gn85_)]s^fP3`uF>D\$r {-J>Ly-m}}?eW3E{=nn֭:=8=H"9%q[:m k]3iNč&&"Yʱ!1-o* [ۊmep}il$jwV}{/.mt]Th = pZKgeOZh–efl#lq{1JǘT)d˜~㚆jU&`8㩮:=K^gq$BpA 9Mf"^ڹ.?e6[\(IC'&VRyD/\G Qo9pJ_CzIKYy>:f;U@3Oe{k  ͿO-o߽+vTi z :&½ aS}5-tjF i#@{s}~#xqO}$mJ=T4 ~gN{dy.α{:uJ%bTJszP @(j n8XeN}X )5y=JVu%[;{a4$(s! _EM^vpN䚾%+"@?Ca8~ke;d漻b@afw'$j2,8% T0@ʁ;\'H\YMcOԥ4 ۄJ0AhlۥkCm/BnW΄޼q ?GrZH$̉v<]r^ VIm,ddA=qIEMYu8WB,qOxgs\xNE5(m-ItG1"" S MPsNPq9<<~k (bW0>5Y'&vQJJKSSOEʘ;IFrI$[%]^sϱ`躔c+qt0Gt;c3QM.#'Z[2:/s)~h~&A7/WzwG$],r64r6 ğRr)v? V t;FI¡)wL޹G ܒHQ!}FjJmd潏S%M;O6MneH$ g84&9ζo1$v}; 8Ϡ`W] kKWIlYp223 JkƩ+R!;] 7Z[" R}B"&=*X!870ϠU{o&-Нql<ǖ8?92'a`4w]DXK&$ؤ JwK+H۹!cB1r+m4mI$3̻ ڋe-fY+E[i%QA rB`NSRf/CSҭgQID*>8jU$AռQAq#}ҸG/m`>Y-U{HRp 3(-z?hrU{Ov>GV_o'JI_ھH 607crƫ\gfo<?<}FՑP {P}YS@(P @(P @(HW3:ʅ܂Ts񽩰(hO"FQIP~k>OeQF Cd O#u8C:" kpB3kixgMU[>rdgª,<͌79I>+L<Ơߛԯ-rB\uҾeWupIOֶr_.~]q}u]iDi.֌tP1a;;9pOwi]/o8اecbT~\3,: j-[L+H9cڷK(<|;O817>VK}vF;ZVEXEUPɐX O']E4I]$QxYԏ=: {,2FGzSTmò⾨ז= Zgvq F8qoG35%+L`ޜ0*{)]kiqrET{9RkWۖK5 8*W#ŋX5jr)w8ݢDu/#;ʹ#-9#(ڗO[Η捑`u##b/ n!\Zk Ĥ{#]3oS7gdN}9AtW|ljk?JN/\H$pʃj3 p=+A=Lc|IJ__\y@. }= 82p< UQ z̜o4$50ǧRWUB3E8&rnѻ#{8Җy3 bV"4T .'9g:95 /lL'qE?3[_WQRvsTƗ̚0 $?ˡ"IB8ؼg+ G ϛ-g6߸6{38$CZ@sX?кHZh?Jw1d/*B79sP;q%y|nlr1@(@vEGg$vLNhP @(P @(Pt  'h'W-,,PEwT.ⰵiF6Ywc02m'?>x9GqiEOWbkr+Iy?by&:(5ٵM=ė6 򹑷81[M4:ۓJłѯW?l/PS/veNgS4^'''O tOtePs铞+\$Ҷfo5hb{#pDG#r[W yB6I Ia1b\$]2UIryWgSV[ETLA Y^Z+U'1lM#7gZIe_j9_ͲT>@9'ںN&u=Kmn.}n {+nJTٷ hN_T~okWFnN4x_1kX)Aȝկm$SsLsڳx31lt̞lhv#"dp KK1TVRi79a?Jy#^ř:̻wxvŬY*S'M_j{4gu&Q1r6I=o_MQkK}9)3Q-L)6 ~ֵ'}ňវ3꺗T,=8+dʀݾuS}W)_3M5˜1%KTN5y2@9ֹN_CUsoi%5z֣Mze!I'߾~uFzUpۃg %S@:"Y+-2|!`;wgy ;y4b.$VX FxF opA43+cp,bp1a`݋(ũ@@۴1H~Ϛ8&B5湥|Bn-wd=?eYSjڗM+ƣ1UY v̓9;0 {nf/n86w=y︘AO$Qg>b(HE7"YD'o^bh$I HNԾ^•XYLB-Q‚q;y9Gש4,En,Âw :XxEi䇖H_x}8Qqkfj+EW$%zy7f`IMlOou~-ãFrCUKڕkԞ IqY\j.m {Fc,V5fu,UAG"5#">x%.)8omcg/3ddfm>ERςUSXʎKlQׇĒ$X.A83^9m]"A 󊥨jđa3Bdǁ873Uuj G^W=Ⱦxd)P @(P @(P ڀu&c)18Hv#VotW[KKX+ٛ,mk)&T=N UwM (,KM _jZV6ёYa1ڟE8L4)"ֽq=p1h `~nU){=XXy^BrbA N^!JSfbYb<3*sni#6𲋇FtơGKpBe%Oފ#fWW{u ޤy&-ʷD}RG`|k,yڗnM-:iTyV=>1ZQ9r42NvLsa@2R6p?\WѺi]= &A+zJ^[BiҜ:WmZsMu}:U]4: 7#ƣ  ~{vq's)4.vK딌{6Uۃ57@n;T㲘[-QvH*qO95RQ)8;YkU!ǚ褋8󬖝c93zdr_:g#mvm`i"i"VCOG^U#f3zt%3x.4v%omp6'hc~}?O埸շlf;˘mOG8xՖ ԟooxUmxiu8P@6ۭ6C$g5^/='J>V:ƻR}"tZ10!XmgpÀ~xZc ,YdTo Yf2US]k\zc}qY,m9YIc8>v|W/EgE2T$Z,KM&ռ?_5WҲʢ3\ԟO[8 qnʼnAGΪm,xQ=Pݗəoffot'`IީaZ翓 PUIA,hm1Zmӊ%<i9z\<j|IW==d5ca8\Q! 3nFHVPDl /R0cEYa $ u[+xrIz\2O ڥ19P @(P @(P @p;PGƐ_Wő1Hk*" G|wj `"o ecϡ-PokG, +~Zz6t|`CIc3{60*[瑜;ד[9Hi$f_5#/ FRR#k.0P/jpipAS2̽d}:)syr+O;er Ϳq[>s(j"/B7l fp{/ַ>+Sk6%|rU{k[w'_T}pt6-Q?RQsu45Ø!V*G2rAeN1]= sr`uGUU|2?m**;=j'Qšףi$dt<2!$0W#k$=Oְ |Ehtnf` |#1}k<,#ETywϥ @6?5s6H\QN)㹻VEIǸB-\jX6 #>c^62d h|5>A^'6JK g_;o?I,[ >^"P6RG~n47[RGtIVw [aBœ7+ncF}Wx#|S囫k `n%!_e,dcr<={WmTٵm[{Tm%XgK)Py#ȃaI)~ `xD4Y{t-_N?g$S8&4Յd,lb2F[VK)}t|v";{feU`ɵN |@lϡ u^eHhh vN{Uxl}6h&an=]@ `r;dXhSij 0wF`c dYHIH434~jj >єGedq| ]+`7*bK(/r܉%.5nh䙞mɽFGl5RiM3C1N31Wq1=ZG[oRme$3XAS|ԍ~QZ8m$1LbrDyQtIG',&:rM$eǛ}@Tj>Md-,hՖG1S-&m> *Tfi] @9V[K# 6 nb9"I53sx$ub{̋?Zߚ@( X)`um\EF"ߣ/bcKZкwRH|\n,a ]yǿƠ37gKmht9ofOt??澛!e9FR|w,ߥ[[=;"_³;T'4P @(P @(P @(jZxZ]iJuu(Yr`'r~/mrOۏtmtPʿ:uI7 $6h_-c1';Im kIz?)<v5RpCkp]8{I;9'H+otS棂YK{,"|EPR`{ºUc9tYڛ9$0MpX'qZj)fLq:K*+8^?ZbvW{+l%k3~Avv<Cq),T[<'8O~MGO?CSS9bheee@W2@Ud2Ipa{eoƫBNihF`f3{Vd=Qm+KvAuόUckʦRO\Rtu"8fMG5frHBKj(S'!Au';geqӺ[_H$QE23O5{q̑G:"K[5S\ѵH-l,Yn1J{3_Eޡ{K hߔ-|29} 1Og &yrgd 'HR @(P @(P @(8%ziIh|ۄ y#ZLڂHf]\V3 3o<Û%|AP3y54z~pcR4n(ɵ88#N+qLj}AdDL$ g'TcԂ}jmY}t-YS4!c޹>281X |{Ž?hKIK ̃U4XҽŞVظJoGHQ?iW0=*_Ij/_fF4y_ңV<9?*|`Kt5n.18gnsVɖKoJI\*]ǹFVd$rx_fA9>TF뇅-O~MGt1 \z%KVV2 `1\Ԟ^\R3 +]VدPPxOpĞ#ƱEeX1=oW 39 3]xؼܳZI S,[M1>/k3 nTZƷ1pN\w<3*:`tH|fR#gp=9Ls* @QGlsڲci˥Y%+3n*BRr{2\tL-G1)]j9bx|ꜫNue\Zk 1Did.v ]':y~DTJ?SҞ]j:=ԶZ,g U'xU#'jM,Gv&$wO6B9ԕtu *wǭQNݎkF zƽmgl-5HϟKkX)X0+۟w'*d6LMZD&)$x^I^ߪ>z\熾MmNvDjG]f%RsبWg_e+Sג;V(C9 o\H3kŗG<@Q~@?%kZ1PYcf0wC-?7~;}2:~ޥТNV6`{}]];"_³;T'4P @(P @(P @(jz l~['*2 Ҿ$Twq XmXd2UpqߚtTZ&)2/m_Tx!\>cvv'JM˒K2qs HᐄQҢrZL mKN.$dBR0[d=J/iK"( &du.e(SwɨW-̬tA_歹] ݢeѺ$3\qWYUhؔ_Ca1{xXƄJky[85f oF),㓟ɯ~v)q4]{A'KvY+ꤣ ޕAIye$:4ZKKv ʀ`HqFrI#@׺ÍwK)u;vK2 0 5jQ8ld'cJtɹ|<-KQ_m^ݴ>s Kg%첁=S*r Xk܍NIwhн?yy{ED$lէH#αGebS*+FK \m˃c}˫Ȇʯ$3pzޔzc)؛D38Wb4,,"xX&GۥBb)2O @nH eIfIˡ-X7.0T9py튎{C=յ-H޲-`yHbd$mR}׃y%ŞL`0>u(ǂI,#4MXr> R>@o%f-#1c)8? }NN:7b Eqf![,sr~3YGc$+BH,0'qLTo . Keo*2#|Xf[Fim1'| o )[jRƍTͥkD&}K{EvqI#Ŋ@x{U\tR}ͥRv%՘e2~XY$9ue#`#rR|.=Nc#{7:$)ү[%ث\#]{O-nn>-Maߥ-:K 1 9Rq9k[/Fl2]#tH'54k {E˦kFh4@l`ۊ姡`}̈́oyKt&z)LkA(G DKG63Me]Lfx|ق v{qQonE :piTLk? Mvid0ݲ9ȎMhforD L$ q21תMIcз'pMWE tQR#2F= dT.qE]^UJ,~}n_>յ[{NHk(2$]87%djȥg>{m;Eњ=/X>M$anH85Vʒ{= v ˫IhO}D$" 9T)K3Υ4Fx䐤ɂBWS7h l$’?#X[t1{d"2;|1Z+V,2qЋmc"RX$`R+{ ir( IvZўyGIkRF);f l`xSo E,%kd .IWΉr02sep3Xe`Lxw6ĐXɽ$\m!;q*K WѣӺ"mr7n6ǖIe9>Q(I֦{~jsk:>+%@"yJs~5SvΥ\^GƢc9 r>uzcvl4j8S AbHSj[isS}? A/Ꞙlku_84;rNҸ;ޭvEuJyXi+=CxZ խQ51w#8_>^U*c&_OxtVOym<|֭t5Ҵ(vo?rTV#囟Ï.46{8йkq!rb=>fj[M gKr0 ϥ^SRQC]8g^J h(D K㜓wlXY>![y/q}]4Mi;T'4P @(P @(P @(jTuPL1_$]E xcyhQcѮ 8\N$$7}wVᮙV=].1:Bo#?Uz%z嶖9䚚'{q,y\ǪT;[sL8V݀M|[|u7JtgK]n\wH`%++7od!mj3>b-dQ 9¶2̣)Ea):mi:-EmpbpK |H%-JJ\#vxmAa]A,qIPd>@;A9?:|.]s_CIsL-SfcoyM+ d$K{aL׊rL?by|1b$1܎3cFkx;WPI5'mI|ۆm%K ׵I8^\SPEJC$3-#".‘MdW BI Ҵ];pĒ@#;3 qs޽^{t1nZ]9[*Cs?.3REd~g7l/_tC ׵TӼKK2C<ȷ-q)HD,̀kҩZ^M/i{<];:x]eneE22 ;WfFXJnKETrGc W$J_\IkkEPfT߹ WqY>l㹆1yaE%L,q*\# '_w&MΝiZQ?QfX+ T ㌱Ya6 4HZi$Pʜ:R3(m$cZJﱾ[=>Ko؛δ4 ŇU8Gcjƪ_ܛQEp_z ­Sqq+L$^KѣuF"moqںB琍>gSmG[!HCOS}vōt5/`O&>y"4eT8TZekMQdkM>]@=9Md\s. GaBAOuĸTdvlb+"[D,fxvP&|XxqڽX@]SwTR1Aso+b85BNj2Xn<⸋\VS{*0Ȩ\ppAhu2NcעtSt?WiY-`I#k(>nlv Kdo߮qm ;9$qkKCrV Y՗UUˌ \dcx5j|a2Thd=-m^N1Z̲4b7L ĊQ<8 W%JkMfw]c.L@'+UVN5MdI9`Vן?;j|k>D}5

ʩKj<a~9X&|^v_Ƴ侦ĽCnEGw9$vLNhP @(P @(P׼O-]Qdb71܊7o0 wх/|^^׏]UzYdimD"xRdBx;4d@s+VWϟl40K)<SR􆵦6bGd؆27akpit7Shjn^.C#yTxdxg͎ e`^T2=y4<.FW:dSs\ q;SAowqjmk2-c5y%6Mh'0{pɞvʺ Nu6MFٚLh ^U+Q,Kk(Iq6A͒x'T:w|Вy|cEPQ.XecEv-Ip|C695Ŝ6fKf-\}EMTӲ}Ks,~xiww6fw{Mq2[|H>8}+N }V^6,cu5zNׯ6kZ.~o<; HE1qUwE/ IpMAGoq4V)H#p@w{ϡug#D}FLD)x\avwv@#fKq1R#9ۂ&pOǸ];maRZfV '͔ʹ"Iop@N$K3Ĝ~ʞ:*<~&Qk#zR =.I93Ok =U&% Ʊ4&|@3ܛ!ƥپ)H"QN=v){O'44;伲hnP23`EKyY\Fi=ͥʷ2VI% I g qM%6?O><6`TYH#]nX5Y=E" *ߊܥ`7|D3x,3+G(]['}Gnɒ{QA\mT+T88gגk][^{thץPRIT8ۜZg=I"^ɋu۹pg*YP`辑Y I! +z.5^DU2E'tr~&%xsww[i^+lyUeuB2;\$ZVI⛠lti{kq-ؑ"YDUgNRi?(yo*5l?GI)q uDȇq$&Ga=봧MK&vO~W(:I] e{]מI+GpjM/ϝȳR%:G j4gvvGҺJ.=Ff?hXoaRHɰ#7NV᏶Kh};sy;շBY|;( Hi-xƎY;X6Q H'8~e\!I˓v5}muj 30RDR+<5~I;쾧?iG> sHR @(P @(P @(8-kGU}7"Z5o-1;s# dgLfvtޙxj`2(5y$=ICGiZ͝6?芠cU3Gn$_ܲ6;q?UY=Q6nB)H< 9'9 U#u4KԒ4h c@õe8mzsXl^Cnn9S]o6澆_HSe @#3G 9Zk$lΤ=k [YN+D *xkѡB5MbtƹYUN>ZkvuMA[+3[n]~VOWcmiz[T^$m]&[EO@8?Mn_#qC (sZwSZhZ 7E&cQsjZգ8{yOQզ1ZfmL} .ytԯ 7X*mG6IVS>KrBcbeR~tɞI"L`ϲ[e ` ͂ThUs2+ ֥,3NWtKylBrA$p+ ? #4gufmu%xIpyb0,>T;~ 3#Fr G4"nl㼖[vS<.4_gPOc.f\.9淺(*PL-ॕUyե[4?z_Zo=r ٖc&aQ$œibq ?KOd=΂}PuDECoO꒝7Vi"!w9VYgɿ XeX_cNx7Rܑaޣaiv[. p`73qW-: 86qI䕲ԤX%t}B7\=iKDoZ7Ќ{yF^7݌s׵cyoӬ[ {(q t5ĸ=:}vqwqdĞogY?I~54Q-%Qqui7AqjiMm>ںwM XYKJUͰ,i-c N)2PWbS/T#`PP%ǂOǪZ]4tUYy+b7~V_Z\\wץ(_?/lra |34m5u.! }d 1<1coh[^tuE.2o'1z e?w+s18|_tkW"rHR @(P @(P @(8tuH`V<ٙ0y, WVMFKLh=zKw,V%Y)ltwԬ%R4i#h;(,Oª"GV֠xՆfPhdsN#G8C-6w,2nv)p~DZ,vjhy*0yzp+_kԞ7PKS_y#'qU9V| Mj=+G!$L6&%>R~?/j6\aR3q;T21zdo20Y}\-p?QϥKN|CߏҾɌǺ3 & Sx7Ȑn"Ej,١,nm1[PC-rkM1; }OỦA6x2IȞnʘۜyo(cm:MVhYuA{Ȭ'J2Ir:Pz_YE$3ItFY cFe'<=ܟ`7*Ǐ̉Fi]GE'XG3/ȀaR;#wVǔ/}Cm !Ka\An`]~t8:F$̊i>溸Kc}(577^ڟw Mѯ l׹٢C<8I$a;Q]bX S·:P!%O} Uiшy1չPH>JR!WGx/Q5-WW[I.֍1w2'c9C+6'9SS7kEgy{-/y{x:B$v85l(kMF+w.;U[,5[ ]ʹpA5[#՘J+/ףݾ_[=,E8<ʗO7'jv8"E9TE=n#u` V@P2FWUu=ՆExk &9zy:f6ߺ#YjDJAz oCWnN8Qy='}kqd4"os,c8<ՙإ^`J Aes@㶲k9E Ns~O9 E$$f_&_G "}e_/VWnA X8*Bu kԓ5[hfeڇU=թ=A8-.Dhb8V**,#6ѫ{FcqYové<$߸+Y{DVLҩ9=z.7YMWWص [=LZ~BM|_x浾#]/|4/J#JpDR?~zgBf~MlUZ??y; w"#䈒O-NF+>xk2Z'?v.}Ns? \NXS@(P @(P @(@tL*UP-A6;5VƕZ{ Ƨ< 8mHTw'|Sg T"@>ёZR5(_nԌU&G Rܲyem.BBF{wc5f)aHEnZK;|/&V[(]v]I0=cCU o Z&1n\)7<9w{1nI?^qH{k-ln!(rÑ9QM`ؿgĽ3v[.u{,G"D1m)I܌M4e8Kӗk1̓6,qպ]ou+o"n:oʣ7( ļ;Oζ/g&?mWNXtˬ[Hѐ+F*H 1\/Prp[Tjkrk]Bٮo/HM\G y2ӡc{=9$m?Ny1"sMXb;Jc6G}ϥlVEZ!- qcRI&ݞR*3)DP0".G>ίͽ>6+X: tէLu jvMr;FI-@\`tm'3vmMN1M9RZǻͼԣ{@1|7xIT>}1hдYaim]ceC$'$j峕3_?c.MF!@~uU*⠢PBH?{{V4me-};"+VÌHep--|Q\FLpυf.uvFȚ-w A" .6n:پY,V>+[ndY(3m\ rk'ˬcRxM_к?L}:ukMfzsPڑFw~mpwc+|B>{=jI=wI>RHdaBWyQTỡ$je?ylE,d3*zÎղN2N$ZB*J&K 杲bX&{qu<\TO#P{0*qk 3Fo\r~Uk*P7t N[ƑJ;@ Ug&,cH$p;+?P5=O(rh`|N8_ ({W;"GexQK d jOl)eqߵWxw=CҺFJo尴9_) pO RH1FM73My1o(]$ fk tk&pg,<^jT(;;%. ٿaN^UrOa15"ъRN<[+`:vo仯3Cnϵc#'ҶQZo3?7Cz[꾛=ei6"XLAv{SN{EQqӲOl?Ytf%E+˅Ai&.3tDR)## &߼#{,d/|;25GھF⼋{gjKtdtY8_\fZ_VUpV>΀/n$Zˏcm&) qae(ΛtrHݭb+fZD͍E$i 9P8? \:VJO˧eջ^q ٸ.{`rÿq[K83ɬDEi@*{#F}ZS-?CEP;Hf'E|M{͚|˨dMgW0kr/m-w.Tj{j69?Ӆg]rG \HG`6%{8=8k"K;r(߉~"C*{eHR nQRLtF)uQizkMQۛy^$;qLju˃q9?V[, m yܢːgq*d`qdK'5 ]]::FݤhJM$r(ce.Y"[ěmDj&b[A1ͼʲ <'t%GW+QX h;Sb6#sUM";-U=I K DHB9 zH5 EXt^^qYo_RnA`?i\$2ߠ`2F]l=}'Z295Â/HV7œLUo%+0Ӟ<WZW:YEw:wƑ{1|ޥfqJMWS q}*ZR;η2*ZFTpfY)슯{QEJᬯYdb>FLV+v i{Υ $/~حM3Xk(cGaر?o-԰u\C/^2]J%|!x*զvXC8 #PpȭŽմIM0U <Ë>S5]Z^aΫ (IYU=A5-5j\"=:?g<$XXUScWR2cR6ߡϺ>uKGRy^茫?Jߪ4{X+/#Ԓ@Zʽ-i>W5Y9i6uݨLYZ.Y0(9$٭dy50_ Swn!1+ˬA2H`ԩ)/igx3gtč>|8ׅM6f4?vKr!Þ.ִmHIhRљ) z 8VpnI`c\i<%+8`TFғ=ަ,5nv-~2[N ϲC̱>¶^;c3Tǡ_Cu[-$gs(5yl;@@LW?5mޝukp&覈 pİ.Q|]tm=g{Y6˂0r{~ʻEo-J^OẆyrdaJ3S)[(.)giϝr$;w=ڵUi<l"བ)]śnӜr>g_g6]PR^&wL푂 .Ufrq*9I$QHﵙ!\PO뒋Ld[Lϋv' dDg5JK95O-ŻM젲,TTh.VA+ArqLŧ*kK؜'"27Ǫ|2R c׀q H ho"0I+m+'I<7? ԗ7ZAsmJe`0AՕ\<8g_+Ɵ>T$VM7M;#Ѓ[%Ur?dN=_W_IiznȺu%J>$wUǶx籒#5%[akq e- H$T4N=Q:CoC:Z_O/ n% 6w,3kS7S[ܳOVzu/"]CQ_iwr[C4nջ ÚQWIw{Iw}#ս㎓Ew"ޮoh찾pЫXWB_ďT69{=Էkk6:ʡ;=2~"QMͪ$RqYh?]kmGAg4>k~]V`I uC>o>KmKX*RFoe%XAB pdMok0N@lu٭θw vYGoC+.Y /'>]g,7LNBDns]ܟC_¾2GjP @(P @(P @(@x ;K":_n{\X>m,88qj֖})51yS̝'jmo%en7`T SH*A|4 bYŭ(XW$~ץ;CV{3pDG6ݹ~#Q- 1_T%t`ݜ8y< X)MsZ4ֽXcT%n n7d3~ %zS%f1 Iq "{$I a JK$/] mYfRHItd:&KO >?<4G'P\h xccxeFwD`ߌWMroMNMM.5~ģxx[CtnLO,/ ϧz6A׎]$w'4R,3F 9u)Aw[ReռG#I>cnɺA'ڊ!KMF~hZ%Zi67*SH˧˖;p|x`95c$v2m9GddynqHlq*\Xt= 4 Y-*biK,"1U I8 $KX1|WӶPүޙZv2s!䐺On$)T:=:*9gz_Wua_.'^U%[ܞqTRDWPxaN%72#ϥaBԓXmbT};%:wJ^[j]KGMaoSهJ>]?SmODZpW+ƚ,u9P2A^ ᘷwO Ekp ׵&_$ż~է,=x*;Qe'% # LKX #0 6=~uVӌ;d@Cuo &`|U2,t`X[ jX#McG$eƩ]Njj&\uME,/[[rbtsϻZMT7ԻyR_x];~.; ԖLVP(HqAcV-R.-iVMmx5ݣ+o0"gXV=QI4.hm2ԉT9pCsϦj+!t}C Է\⢺qz]CmL@<3Z)Bj/NRjO{}w%q8b9ebʪOs޻].g2msej[ܻV# ?R}gԓ]|RzC{ wQgI΀^˭v-* d<1G%NSjOeNISC~'Lj]g׺vQt-fRƫ[ήx6knfE.9_mF=D䌑ڥ19P @(P @(P @p;PQr+R$t&Hgs,XXr־ KU6b=g[&4Ϫ,LkJD;[ eVytj&qN|*5P+y{E=+]SH'd8VYÆ>?.zSY|ۘWΌJYTy`Ҭ6?G@^/9p<b}lΘVYB]˞ k&+ZҊ:/6;.}C$\ b ù`i 6wBf UTGV\A}jQCPt&.F@B1<Jk8$.$ɿ92H|>kvZՍ,W-qv+BJa$u}_*rJȮH4mv!Iml(wx5Wȳ[VJPpڑv@c<׹271#g8x0VFH O*KsD{Qqc5BbNfh7v5ncR@kK} 5Eo&]ٺq .~qTo`GM"W`Ol[&tcH;H[M={Sɯ{!Vt+Gp_+M$mi 5m.K٢@RN}+Yu.rN=1xG}c(ѳvg:ۯ rx$5qwqp9F4~$܌\K#~ʓgNZLl[ -oQ=\,-2)N`i6P[X-专̎,˺ɭV3t_f 9&?㞢t[GX7$b njV0NȤ cizQ/ۑ#C,0Xy#*+*F.GZ;'{݅$4dVʲGWev[ǯCc-=xW],t%p^A$8%e#/\ su~X owji%񋬑y.cVbBz$@$5cl9_~GkV' d)P @(P @(P ڀE5ϧzb7N7 vPn O*I *3Vi+ڝH^x9Z5\\+=F(ש!PFiR2#bw݄aVuo!m;>9̡\'~XCsˆ2<2wɧ65q,wzdLȳym+߾s01"pE#oQ3]L"vE]ܞ9 ,#'vLae˄=hrSXK:uxP,T pnuQgbi$K:;u]cbē=Idt?R]X·Pp[z{!d:2p'N_ehU6Ap |l5|qcOٞ~?⽲DѶ-Kn;zpj1Թ]~C^h~!n#I/=FF9I?,s`ط[l9fyR}'#u>]oex:7[ 6Г1$tkeyG 2 _W4զܤ5QO2 l'4ÛJy^G߹N*!6ɣtⰏ[gEcZ=ZbJࣇet`bl_+xUji`Dķ52jyb݊jlUs?>:Y^b"OMG^.,tVF*,'%H=´J/k-}݆'>8fqr\յO;?-Ƈ}OS"HQO*AmqWxre0Es2;+;ivp{weEneKv-7gVlJ`GU kuͫooBWL=zk/m JUʏ>ⶰCa~'7FrCAiL+)= 1gt#)mM";Vs@(P @(P @(v?zI:۞o.ZK(X+qs| MOqq{|>^QVk6{-Q۝[EǼѳ|}y]Klq+jcQ[m-Lls`F5EгR]Ѵ'% miRNqPY 䊳 !*j^zIph"{^c $h<'s|2~5(,z}W(D2W1e~] FOg%<^>Z_jfX4&P rOqORqhwJ#v`Jz#(5`[MWOhYkp§'㻷W"~)um.̈X`T^4x`n +q .[9L} LJEbfkP -7ئ2 Kvn>?X*YEeg ۛ]Y ևP @qCM{ٖET ukM2wlXԚ!M  qVaGc2ۂ6{g9j{V+͆ФɏLck_i^e(7nUuWc[3njTHMDT'c 'ԟƏd'hds@aeiDDZgwGc[ͫ}sݎeZk}v@>>dö́;WBQ9P @(P @(P @p;Pz]s/F+5ܖASH%Ͻe|:7%gK9)>%,LԺ=_Y@)cOu[ ~7mV-њhiezF kڴivsm!Nط ]Bxvֺr]N٬QlqDyp3j*Ot&ޗΞ8b[{h-r׶Z4G+c{o ;'89\\d}+[=O4i_ ;}7} `SSqk/^7yo_jv7F{gү?=À0OĊtYS^dqsJ44hV56|E+s10uдL-^L{{V?3A8vJ?3QDܑz_W Qt3%}*Gzdq+ڌ6G%P0UF;|V['ԛ e~u-e62ZDG&`kم]I}sE[5iۦAxICc`8GOU3Ox2/-jg/QznGWmuk;(w9 nޝ{ &xuJ06K=Jšҋ[ط=]u3,tM~lO;;zjz$1rECY+[_QVP @(P @(P @(P @((ʰרw?/EzQt[.è5*(KxӾ>+<]xz8D72ֳYL HP;U857_gW{ww8bfexvWW?F:Td(x8E#6] DP @(P @(P @(@~|,ˀ yf R6l(ZW>wwwu%L٩UPm7{OuQK7dQnLԺTm-H`cDE oWaj.;[2g6Suk嗚KRB7IǻϦFG&"f8F=lm:]n92.'9>}*HEIe8Fpn\p{ {r082Kw Xw8'12Eݞ[LOoםb;lð\;Yts\}+ۧ:heJF4p4H4ӷ֪y(N;^Jm@̘88*^35Cmn, h &GfݸWdLgңd럱][/T+=f ]*l`a=g?YRYH",06g'տ*R46QQӫC1]*)U51QݏC*[pM+ybp %o'o]`zdfyI>??n4fWP @(P @(P @(P @(v?4? SZֵOϒ?> BmN6F?nkMvR=>W7/yR'h=k3v=-io-ݏoAU#6] DP @(P @(P @(@xA>w1x׷iպݲǦKȻ0mej,r2Kzzm;~D[6ZZOt欧zfxkL1YIN(jjr|7v+{s=]\s CqfRc*s,gY:toY";Ǽ(ڥfV1<5Y867y2\hv4Dql,Ւ5-3x[]ǙkTNj|WU\F*bX;v=Zz875KjފZyaS|Ś Fo"8㓎_k W*1{CCR=#:Wyq;c vsR5d< d몘suy$ |'-:1|g#o#><~bYg=l7fe>msqB \vl.Q|WdaJ$V`H8 n|ϧZ ״ئMwQ٠LiU#үU-HrY/68py{[+@(P @(P @(P @(:~h+gjֵקU?ı?DxNFY]6`w>sk۱M>b^I瓁;#YeɞOB;:9e`lJr=GPGkg].ܾ'5Oˏ>7?AWG #6] DP @(P @(P @(@~x\]=I( P{S뻏~y'pCXޑju6#Kv<18JG_t b@8ZEJ0|.:|[e&՞9ʞB6Xb!5nʰI]#a[6ugs.isպiϧ>B q۟Wݘqew]GM\D$DZ,~vVOIJ1'޹rĪYR?h*ટ z%m,8&*<7pȎDl( $󏉭͗5Aড+ƾcF^iX ҂)9S[eot}[-6{4XX*P\csZ/o~fYOQ]YC o%sx wv\6 I jqo"BQppGԙpgeGYӬR,ݏ$yV6 9ҬR}Ku?{ :/5K cU][{79A89-[}6+_F S]֩?Lu&/!e\w鱪ѓ8*|CVk kRK/L\jV..`xFבQqHΏJq+t9ӓ~M9B7|x#ϩM]<:zise6NUD{2Do ifSFP @(>,ʠW g=ko#$ JE;b#&[&XÕslNo<#$FG Sz4ȺTP @(P @(w.]WtƩ5͕=kwqm-/4RCLΣ5/K۽=/OԿ5ݯVꎈ5 DyJ"HBs@r}Gz+K>ד걌eIPH>?*;=F~fIK]Bn8 q,~h^*۵B-쿱q*ryA~4)mK2ZG DsV\.Vid[SoU)/# NJ P @(P @(P ڀo }-rUznoͬ[FՖ2'y;jFHWG 7sڷ?eadqկ_gK#:~ 1t366ys x=+}vc6on }|ETbTэu[YO&U[i>LSnK';mJ!լ2aۊ¯j? 2ONi Z;cUIouԳM)'ٚ9W_#o ۶~"ul6`}͓Q3zzdGiId")착/!3uzr~\c^ii 2ܧ9mǐ?_1Y[VG CFF[iRx=Y \#;u[+sC@(P @pMys Eer2w +4GP @(P @(P ڀhTa(hĘ Gc~yi6˱֖ɂUQSiI=y^'pyCw;/"]/F~888+X.U= [8`du#v}q׵tMeaxy.?P{DfMHD FݰI~nu /i?&:rpMơa@;d${ gEex_qR(tMmB[ ? mYIL4ZYXRM-ІϹs3AВT8lv#h1nrk#ɡ6R@ǡX-x唍 þ,0;n$ sm>;kif5$tIhm^-:ծ$X%i HQ5O jjrxHtoJqinqܺpS;(-ؓjʚϪ*9E&5ՓDr\ǶkZԸAˆ,^D$®f [qJS5TN_=e (OTrޝl}W$v'+H^a;N35j& hP @(1d&x%Ə= f= 3.n,+S"Y<6IǦ(GXn8UB%'oaصD;|hPopH`cb9P @(P @(sV!/.$BY'"sZoM}]WꍟZg_\]hNL򤱛qPFUf`0?}-]ZJ-K _M40Fq$P @(P @(PEgtbULx",m2 xj iK[[^MeJ2A2LC'v2rr=iu,Τv5>mc+x'I8ie TwPAt> +U̜sϺ.%莮ILg'?*^ȶMZ/%F{T)P q'ٱrp}`).l&e t=x36*XZL /^oo. гHW(ۃ<;|/^Ԣ~O0ju w;O[ҹV;gYUZpI>5hmf@!$1*֚c!Q6KkZ杭́uϴOk;^n>I+ey5fih}LG+2 +>YgdibX}%UȩvEP @(- G-rKl2wK yzPۛ+Z/2f:NZ->Z$[j`N[NNh2(@(P @(iryy^Ywe\jGMkj3i'IT5Xpr6I/'d撗ϯm|)~|`ۏ8_O}/`ѭ(أ'8 1_r8l6M/ v'~!y.-^^LN|lT{2;w^v 5j>⾋?)|[C}WrsP @(P @(P ڀ+E]bhnHd~G<|g&^^ܝZN5ۼΚ1Lh? 8،K&GttF_ ٭'J Gٔs'Ao&qݵdQ[koZLb,T6G06T|Qө!ڍזwiZ94dԭaA\fy%Sj7g20'v0FxCgu%)6M t=5#MI֭Owneq>^Cq|MIQWcҶ3X4.-Xv2FG!ZJJ?q'}ks̒ F0Vylٮmx9n lUIx\]K<"Ё-p>t?߰Ɵ[Tێ͖f:t"gX|cIV;ld ƽi[RxQeѫ w_ӭQ;粖TΘiXh6{deU]. n'ҧ/<0$Fol8?Sztv*:&votκ};_V-ȳ^Rm η6"$:mV܋b20BSAcǮ}~g;gdP @(ԛmqhT78iq?v-JńGKXK2B+̭>BJZFuf~9 A< ` 50dNskyi\5H3 c9 TצT`8| $ѴHZlc'~W'ϵ}B$.ד')[*3W]TP @(P @(P @(jJנtav>n Q$lQ&nGۊr/6|ᓍ躎5c\޳EYx 0QnX"S[{7Gkaw:a$s(Lxutׂ$ho"/%Go2#jŽNx񭫓/6KVNH1.}^ =±򙄹XeYQxԱF5>7a\3Y/F aYݷPزSAGfs}OuWR{uװE]{ind-q$*L8Ս-5I8_jT=pOXr=[o'>_ңhְ9xbx=*菗H5fIi63:}xawʅʴ8se嫵Pzf+k&I#yIpyc;Q1{F-u(ἴiVs%yv/(,W}+^9 Oh4ռL.I4#.Z2Mnn)_i3<$~5Y5ј@toiQ0F =h늏 >}!WQ[C#9:}njeY<"Bw[Cqz`+r"P 02*Xmc2o.W], I l; W'8?ZZKR0j6t뢍 {V[qq%.B|`iA\ߤr^CПAT*9)Eip{9*L` |`BGJyWޡ28];$ԙZI^*8>$a]ʫ,p(ڊgNO$*FW^SXk;V@P @(?o~Ѻ:RLլu2K%2BQk$|;N1N=qTkw~ rMh=8U t'nNpo(%'6}QۮoVرL{Ǹ\clsІPM7앣^x]i-I"r&U,d ?gkqIݾEQTqꚅS[LZi{k޲H9\!%$U߫*ˬO#WVȏ@(P @(P @(o{B$~t%q__M6u6,3=Yy4SQ};yei^ppNϧ$p9>Ţ9FAxmms՚}5#ϗ]({A,`_lJRmiUڊ3>By"go4DT7ɒO*BA>Dz69.VQJ߃s*zga%uiZR_"}>m̋ef#jl2;M?ai5[M@3%Y}qGNIRuΝCԽM波[2^ae#:CYi ( Gk3ھ7z>Ⱦ"\֬⶿k]=v Jy<^哊~Gdb} @(P @(P @(8[>:I7/2Bz{+ꄥД". w8=FGcBQᘺE.HAs*%"c=Um4sqsL)9? zi-EԻLCɕZ^itMhP7 }q 5r}Um7 UIq|K@xھ+ZiFP!P yG; zJ<G=Vq}אZGٕ2"9\qo0yEK,d1g/uSİKPїkrA?YM35]=tm"940{T.y+K=%_i[ԪA/Y[J`ʇ+$z*~D>Gzh]3>-}+᱒׬/.m畚5.`\ +qߌ՚JR=hcn `"60c#,]5Hk(ew?Oo|iN\qjmce6>cH"@ cuXr3\G^OCkmaj&l RcrǼ};VNaԺw$_QLWܵGM81 sq{Kt)ɼ<9f(هYV U>u#v=HwH? I;sMlhT>J,9`g۔NAP @(:{ [W n5c"pr\D~bPBA)1?^@f^woZw:_Xѝ*'oQ= 5dMgʏ~i7pM)nD:nV8umP@ldI?JUb+ Rf]9;(b2K+c eNM. j|:Q*+2rH-iAG|[LWGkOFJc>sjXelw?~QutD[K Wp!=%K>~LDۓq~u$N4|\P @(㤷 Ժm֚z%[m1H*AAUM\iZEKQZG%?1Gjʭ`gyku,/ e}zsj3h{~S7O)|SR]L|pEteĻ4hbX=۝c<#饎:Gi:jA )*D}ёI'[rښIw9h|cO}AV}ס/']s^ۧZMB #:R'8d]]EJeerkpmSŋ OJؕO@(P @(P @(?FqzQ85]#(B[U71 N^k+&v7͢j(V"C(p60#yZQ~FwL]v.^"[aϩ9qXcV֑Q}>IZb'1ݞUpu zPrbklaK,dw2hV`gRv5{I_3Cď(_SҲ18tuQ'Si{6T3IZ="jrΆϪ/:ȹlP8,NyWm?5} P*瓪.tⱲa=k$Kb|^QEcpLη!h89AJ:h4!y4fd, x݃ \$}-v'-om9;X|s>\;䙛ab|&(m._g`W]QC@(Pzx#C}Q鮙tk}q.ca$N+KG/w:h]~?wGpO55G:QZZ[Yh11MARb''- l;ġ(>/?\5V~Gq6`U,I.18ߎ⬩nY.'&UV-Eಆ̦ !&<}- TuyT-$o&̋Y ֒KpA<|x}5/7_]Μ @(P @(P @(8mf..dyKn`Alrr;q_ȴlZOi n>͜HWck{Z-oQh6alm)[f4^0GbrC)yfwJi.'iӥP{y~5(SLn[X L&3}1 `3$5u%WSnȍb~]J}1m NO|C~c'}(gu +ҬJs|>_]>o-*!lwVFQ2p3.3iSD<[(i ;Cr'L|9X4gQWFsi{inh!)rdc ҭ.A;&.-Ѩm#Pt'U/Dkjf^[mH">)Z.),6S^dQ>1ս;k7"&O3nd`*Wq{/kqs;p8F/I[lm #Cʚ̌kRVkJܽC@(P @qc44P @(8h|+Ju 6VZE\e YEJxo,Xt05('DjOߦV^L,osPF˽y'ΌQvu=,PvZk{K'*k&@8S㨎v辦x>zC~1Gd6Uf r0W>ʂ`2.Oՙ'b-fQ4>"<صGcG g)]#$SwM~(w@u X,s=I=PȨүV6pj;Q Kwq)O꫕5˪OS'_uFP @(P @(P @p;P)ڄ}^#zŴ֠`:TY&&YIʦW8⤍pذˣ:Pɂɤ_h/# =Rb YF˦DьJ'ԍy=J{rсպv#Ib"zԵJ)L"M3]a^X;bxp3dn+4IVegX8SH$ @p9GS$a'zk`zUk+Ƈ= x\Lkii-eeFO`3W"9te/)FȊ _oCNYRZ3v^9ry2Sz3OxHt~R2yS>N#liu[O_5Ry. f]! /}3c{PϭhYL[F]Dś7Hџ:jOP,bժr^#KCzܒiŁVh#L'"VX!{N0g2\o^LqRWON`tIvא7޿{4=G 2QQ"P-^}elGҥ |{cMy5~Η:4ީ$HlpWtq߁'\6o$q8ZE=ҟu~@(P @(P @(v? $:aoeU$|ymm=LbĖu"[Wwcc3,' U%qGjE%&Kаu2y~^=Ϳ^fy.]B$0$BkW,ن}6j@F;5죷4CG̲&V 0q>UNml(bCSxcO}[pIi.e܎O~\M-><_Fom4 ,L=Elx܈Ku cc\HYKVx55,dc]Z:@d*H GjRILʾ&h^Lѵ}n-@4vY a T,#8954-Z᧊ꚞ&bKg)p!BH;qvs4ڷ6qoj]؛dٞ˸TM)wDCjmG"!ۜg-BϷX<\u!bD{sT\=8;,5&@,>#eU$ޛzʶ)'﭅VyѢ/q=]M5#r<׎PkN$>[O,r9=P x?:r6T1? ,}w6$[|q!Q=Hj -㔲t? Z9IUden2 \_ԋ ""f !>9=]5ZF*R_\/exS{N?)j_CG~,<;ERv#dPTXi[ʑKWjtp'[MnAxc2P @(OZEiFylm BoDz˵SveTT˃xTAe2O7v3_c.L(j&z 8i -6ۄvvEz$tdÜ|}H%W'm=BG{}Z_7P\'5Y^vIR+d FnIѵ^_#"9瓟\ֹllۙV1Q}?Fʐ}C$z2;c_#x_IOA]iʟtP @(P @(P @(jQg_FN Tn/s<}O-t P-6xSltVkZZF 68${~8QY"|pgZëaVc<J8eK!"2?[lTvE(գHcy+85KfP ^}t(t9OEpH%Aݐ+,ţؼ4)t)捣(dVJXEeC: uӭ-4[Z-<(e rQK aڪ_~[Ia4AG@%Ke$34pUϻV-KNj\F@U>]2Bv՛+ᑲi7vH"-N|jȦLzJi:6,/m\W(0Ԏi-7s ^=+O] vQ,!_up j͵y1 {mColr0Oǚ Yvfbs@qd(x]WTF漹, 0>V2ST*t?jkD*Qe='-Wi:k~A=e..58nV5eLrsZ<[K gp+qqY2kPJ$c[շҸ}Cqjѡb㱨2HU3k4H ecǕ3'fc~DXi ̍l9`p@U [[z>d঒ɤ\oq8dXdvWnl]Jv:gm4U%H㵾lrIM/Ě|Mof~(+1ʡpVfpu]QC@(84?zΑgk%'W-䳸EĝfU~ U[|px5%tj0^ͬ;;ӂ;g5\/cj'bZKr/wjvM֕-Zڣ47 8E#da{3XW;a)Ap_˧բ{qzuK8;]UlV»O ²;v](~picN{zDaK($C]+A:y,0[/pDw A]MSq\|yrm:z^۬ lZ Y'5"1_HF8uk(H/U'bK9U;T . mK=+ftR$,T{⧩EbmXk]BMIp3 ()'WQ{[5p{HlAUPg ޛ~gF넺)5m&Վv2GjHDmrȁ0O>]\a. >_U;}.Zdp{Զq-K峌Tw׊x~pm$k5U"ȊX#l~[45㓋ZILUjomAfIvBF^T%Xrrޠԫ?c+9 qU9h{jaCEשb)"u{|M 饸s.ɤVvLbM);;Ep~%gtDŽ>Ϯ;z,Ԛҽq Ѻ%gdoF#Î R*[_M%K籓aw)~hpxhjM}sm18|G3(ݡ(Y-[BI&=3y\N z7T-WK/&%39v8b;+8=ɢƹ(P8iz2i|l-Z誵d<'LPSpx^ jfn>6Ո%L/q[HP @( kOlP@8ϧ5I\:ctuVb5 ,COm= x'c5]KMy1jӂpT#5 }Fu,B'@" 9Nϥl!Mg䊶aC{ʩUp~#]5s`]KlPPsk[l ᕓYP}сr%vn]F-7\J|/FAQn$bMP'GS(Y?ß^w8Uu =!bFSy~kЪL\A(Ps TVrؽ}&m5!"hDܰ8U*'J} QkӺ֜\ ʓnEnµKm|Q=Uē >YϸUa]oe _s/jM,fT2+߃[N Ic'3%˱c?O`Ŭ֚MzPϴ%hQv0*jd1џFίLO+Zu[_8xpHm1132.A Aᵰx8>Fpli6l%8?jԴzyį"DsMZia#|,gou=2b881m.MGI#Fi#BI݋8GstϴΛ͞P3LWu 8OvH95 hϺ@(P @(P @(An[ @23Ff$< ǏLD}]Fp\zNt4> #VV % SѮ$+a)m ~'y3O<=;{oom;ibQ=2ɒ8ܠ?Zi˃lmVpcVw.G mmGA//=_Ge>urn-HcŠ1[(i#c ooi؂b%H¯9I64%N HM_iB`J<PRV_6XjVa q 5SW&`v.!);{.f8db;VSq{`K7Udbʆ98:irʓ(_ZM8 :UP EXR0Ak'&%kRk&V#_#iU;GKX;8?Wa'ߒW  <wc7ѯ{Ҩ?L?Ϸ烧B͖֮iٛy (=~ZY(=9.j4)lW>4/ʗΈ(\UGS-Da Τ2ǣhPKg&s1$KʱQO8 #Ҷ}<575WߦZxvYK5?0ŦKZ?^~l\A%Hl 68OU'Y:㽆]<,K3A+(矏nݑ;]:쌫ίm{yIy-Rv$]̿p@7fK㏑f1ka]5!]Wŝ(Wq8'qsw4vXm]c'0u-CC-kZ/è%ʖB׊5te5|_E*>'ҾA:楷NIV<}=+DZ{ gf+;ta5|IͿx&X~qPUMbOEmoԂ%]ClUkhN;kO=x1U?Q|3cjLͥYq4 y^7fnybIjwKXoQn)"NuΈ5 N4EK@)%9qEu\\WB)إإڜe\s鹹~n)S \' lW*Hvu,BOJ}P @(P @(P @(8+䔅- $KE>!ڧ}{<&O۬๵VkX26. OA=Lk+;e1b"v89䓒N{ߜ1vٻӧdre['8#y ^OGj3 K~Xn9h9o+:Q)qۋI>Ifߌi\v,"Q8䐽m>iiḘJ1c3^)M.J%tMCͧ#v>e{<ԓx59J2HҺXLƘ$ 9k*.vb}^zuG-So47Oc9%$QZ}\-ُ+HSmK?m#Mo]-D2-_5@bݻT,*k|+xM;X9=P ;C&W m8QYRcB ̐8ZwI y*dp{kOϘ:[yB vWnh,'ֱ2 ڔR)L(_+̸AB\s:Ritb_x ܖvz7l^M6dh:BU%P# h K6NnEr:ڽuoKT֜`/9W~/ĭw2 촸QQWd`48*$ d*)A,4|/-Ch/7tWPU>^1RG|ZꌤٴŵBvF;mX>dEv>9UImYO^6[qdv&#]HVgPdA# PRٿo%6j%KkZ|RIqj5r>LX[f~T1%ҺTCu,RKv94]1uKi"j='k{e$z"ݝń`bU:u ǡx~Q,kvg1{̔ޓNH(P+w24vCBp] /mW<qi,׾8~,u($yHX{Y!%$/~ޝx+_1hb3i&X_J[kdquM\g.vJDޓ?O1^Ȭ&8SG֭?-M~J:kQV:`Hʵ oS(8 ܩWNs ڲ)@yQw N.JS xAjOΧ8z2r[UneB$ TV3jizǯL3*6g~.V[辥_j* Vs]i=W~$)!aˍor} I^Qq~0>P @(P @(PW|Al]hRj2#srFs_#NW:n8CTxC̊x>%Be SFXVR)@ =*?2p_W+&}x+~Z:sŪGq$1iE ]ke qT|Y=7Rqi.ȮI)1WL}q#uAb4 =86G^%<%*{HKuA1\Ns׵bhn6W)HeRgjˡwW7MM{n~˓!ѝ[ok{o{ x'OzQF<ܑ 3:3%Guuz-bX<Ĩ֧L_9 [QC[0kq9<;g ! {N p9Ok0 NnMd 8g 1}SzPIw+3-/1POjsSM յDZN:=yrO1E[<\Azn R| Z t}BQ M%+ þQiaupEĆC+{]s=~ϊx]A]x&7Hxc=#_ t ww/GFMݷo-jWG>_,‚nV5(\L塌\: ;T8`[=4s8;WbiYMs$1\ۈa99$c.<S^;~5ˍ+JK}rV3EGo][/Zc.{5fZ' U|#<)R.3^ݭm2)ZCJs^hVG+01P\Ԏ'Íǫ]@zf$N=;Ywv;cԾ} P @(P @(P @p;PŽh5DFN;8(#rvAEj1RφN~_cZttG~kK͘^>f ϛm)ORx] LJyh =K_Tb>mOiIc "bVx|;8$zCV֯#Ђ#{Z啫gWD.ځBdNDcV<RJ~^~$R$+m\AXJYDR%u-ZYCR8 Lg!pTY갩V8y@I9o՟iz]%/J2lebAG75k6{ #yIQo=,6\"`2daq[*%Xdzg |yK^WS[r~oCtff\qb008*eB[im2YYMIe x{ /T?,^ۏAUMwr&Mmtvְٌ{MUդrc2:2gakKВ$ʹnn*^ݪu2cp ??Ra3Yfl @[Xv/ Kv '19;aꟘk^'?Z'o}9~SGW"}9]RmidS=NbA>v?Ʊϝo B^R]H:^'iyVD3=.Q Rܜ.М=Vp_DjOh _lІrHW!5ۥ>-_J.u<Ȓ 3szvKs:|bG#B)%d10s+԰EKX 3^h_+yY?+LQ`@!V֢It(Q O i>:tUpOgDs`b2$ye%D hikBu|2Gh"v|QsgQ BXEPw0LVy~Gzx} @(P @(P @(8 >u_S,KzEӐO؛ZmB m8q\emJbܟ|( ˱ͳ/ZPt׷ߥ7WCg*P+N^TTn?R^M^y"Qѣ,@`#>Y49췄DY UTG2{n#pl/,k;t~oRHvQq\(,&Gյ ٙ-iDk qxHZ3J)`3V{/{;MϠ8&ԚI[,˧6Q_$by>H7i^֛ih[2ˌ]5t*j]^?d-fr{E(ڜlFOj5IGađQ)J/WqSv5Njg ;Ç"S9o5F2Kih2jR$nUwG>m[85(%]|` 3*LoqҺ 6X+7𭧝_ +Ic"RW#Ul"p=?VTHe[vUu ,M-"N {6G fpAOҪqYfǨ/爍0 ~{}EA+*t3 c}{GQ S1P4" ˀ3ޣ9Ag[QlD̘;߾qZ姟t\}/IU2IdGr e(Mc*ȴHُ`yl [;ʮݽs~bJGho"ܩ\cG݈m "Dj0$8FoϭpWl}OkKq^M #^ <$m-X69e\iEڵr\aMi27vPi}ݼchT)!sϔ9;"ԲI/rFGJӬ8UmiOk2_>OH@vAd~ȳa?ԻU|h=|[%KO(O?Ofb1W=mZdH$ĪqiqЧ+͙;hE9 P @(@~:m#F7Ļ};N:P Mz(o]UV@B W#f|Jt)U\3M%M443;#gbrX$I&rmI#=Uok8{M_uіmN=eW>jUs}_~T9E~'A{1-6ι.Aƿ}<Ćc[4bhknQw@}ӝ8TשOxX~:Dbgi_]\Isqsi$ҹ|e2ǓQlXj @(P @(P @(8 #ګ=S[WMj-ܒkKi+@Qԩ*H#8F[Cn\u)z\׫)=Ȣ} ;RՔDd ƭtLYf[km/Pk-BJE8¯U967N (">O%h%Yױ?LVq1qSXg`^7b }9 ߇j3NOPKhm%zʗ(''ɍ A?\V?\6xs^EQgu)dG$UؚQE87&d^-{)9 qjk#gqydwI#iMmQ؎ʧ!6br72\krYH'JYc~2PxjIz:ER} :d:Ep̄XzK8xDfGƦʂrN$`rKi3A8*Qx*>ojw*yRXׄڤ9whhV1R Kn]][C ji'Mg]pv[oޣ١WǾr19ľ~^׳<4̯}-W.p3y-rhH{3'i~!f*SWMscEGt5HR @(P @(P @(8 #W38SZx<;k:]>Zj5;.eܩ_-#9;b;\~l|W '7~Y< EOǭ][ Ko(d1PpJ8Ep>G]qS] ̽\1 p_ӟ>/n2cNԮ-VI,w泖qYy?SuCk':{M#CYo20q$Gs r9E{ir{0$jcm`q ƾUJK׸=Au^fnFtTNvF+jS3;ir">a<Bao4uD2aՏn~׊AO%^nn$jd%P r9Scֶ]RYk(}np?v$࿰[HŶW~<+cC[gW^sӵ-<ϟOckr#xB9n23GMOR}Iߩ[zTim&smi'|7zV գ*ʗ 03ۚFa3Y*o,j 4P ).1s^0k䝻ǯ^.XhK'vꑤupj{Oj+#1Y+P5wFׄgSe@G4q}vP @(AV[t?J3Z5đ[28w3ϩ_Q|4N_}=[ߊuD]G+*s#nf*!8Ps| 3UkOzokdrZMrv?sJu-wa%Cu*y15 ]j"]u zZ6/hto5kz.Y[jriiȲ0%au'Ns'9Ǖ=r!@(P @(P @(v0)xquJ>a_A6ԽO_tetqe"@VKr1ܸWϮjNMp}M}R aqEj_F֡Hؤvo%r zWI2N>;dYZ^mm @B,x+qڥ/g= eX`f͋]]EM,r#\Z`K@8ʼeVg1_Wz:Vt쬶XjrpPɕpyG EUZe׾QRYq\e,zD! H+Qz5Y|l{\M"Q u;H=䇸\5 ;+4|3&6_oXM4ch DFr@n3GmCYKR7gi{+ȯ& [yw$88 lrLKt"}(G% g֯S\lKU.4`,zlY [Fy @`|>Y)2(`K9^_zGMlԺUJEm@Y@g-Qw"6CR?s0E՝$sH:˟RضD8 ͹Jq.n[ܤj&,ndhKH l5pg|ڬ\w%Ŵk̻ }*nٞP^d݆{߅aOt{bKa!>wV6-sXeƍ/S!NH<FXGUhcٸ`?Gg)p̊P @(P @pO7cl)ԓK>1OrLan'*n0O=D>ƭ֞ڬ1>wՖYCI",; A&?wwj|B:_#:Rӣ3Hy0o0KyCu~@(P @(P @(v0) MbO޵_}G/ڑx/{ֹ]SNxrj<>GZmF]KH"[$.K⶞{^hվ2LhQUX=L6Mq=̲mAg0sөuf.X;m*ɻ9M et qK+K&H@ہ[M4-mLL7lϚH$cfr5R1r2p(8#,( ]L]LAGoն*\P @(P @;hM{3򗎞c/55mmztcH(f·^ FZY'c tz?5*s͞ mydhKe y$Ax#ͭrS?2&PƥGFifFN8цs%E(f@tuyHîݢmTRUpVJXgwMۓp.% ](?y[}?<3M<7pGs32ʒǵ A#scguPc$RȬTI&dn_FXAԽK׍;j OPdʂ"S+t[_S k ច^s=WŮu I7x޻8(_O@(P @(P @(UMm;~EFޚѯDѴ˫#渱G|p2̤`qZ$o@,A>D٦ۆϖݽk"?.smJuYcd".F$r' +u)Ksui~60$ar1E: 'FI$)ܦ6G51kZ\]eǧiͥ=[Zr[#%d|U-r B .H5[ȼ&;fV*h `Xˣ4kk[[obd嘹\<5dFuΕ4$XIwϽZ ҋnmux'-֠q ьzoP*< &^%#w\ '6eee y`IǸx#1ϛr`V_{DzeQy;׾mDDgYԿJucsYz#jUs5MN,/$PHq>2I]/o_6j)+V= Ӧifv®OG}k UrMg1o$WX3 } Q[oI(,<"iʱ # Č=z*ɜ'd?m[FEMi7ʖ3;lpg K\3Fk2imrOdXmn$7drȭIW,*$\ P e.Gzdgf+1md@ d<~V5GNM20P @(P ?n^DKӵ 6f FKw+`Hqp+CvYV}ri]>}Vk'禯{wQʓ+G">yFF!2FGWF{KgNU_ХYuN?ij{qd0aʸ<0|r*hmo1 ^ DͿSi5rxtWZI,ĖbNIcIɭursoV}nt[LLGx$s^F^Z>hԴ$Y9pN;'Vy*[+60񃚗{O0>$y*Txd`nhMyiE L@ٶ.#Pp{0iܤfQ6FOE]-ڪGa`wzʹ˦IԜ"[MZM>͢{ -DIv%R9ʍخm/~okCҺ_#vvmz}x,ͺ}{Ա[q}xO@(P @(P @(Uϒ!@$I1Цu6E|,`}V|CgN._q5;.nepC\s*1%l$pAuGGA\:l5.=F #ʵ{XHf*7 aN9d>㪱8a"F]!Fq|% 6+JgX\i51Bf clp;cC[=bqV.XSk" 2{e~dgi5x§(MOZV 5;mnQ`PN<ȥFA5k+Oehm{YO!C$'T䶼kbO›1.X̺p@G>|nyky{)z[eA#I2j#HA݃{ v誈Y_IҠI-WPROrk(2=N/Y.DV`Jy8Edd,rEDFluYt ft.y؃ֆ E_2Y\g!dj۞l_-ܱĘ>ִBmApl#,3w%nXBnnJܳ*NX9lmsөIpN$2ýfA8)#m_=05{sl+.nO#WctN(8$sE$n*K9jb?΀Br~񮶽ar3˅!ʃ5V9G2(ܤ*]"Igy8@r(8nm {2F~[&پm侧?E\Me zO&\AB> Hߜ$@(P @(P @(v0zshdP7p2x,=GNJ>ke&XYTH p>)Z}K9ϡxz)Ǔ5I-Z\6GOe3 >HC${FT;֫-DS\-w<[ҾNk4X]a+if6gjk&H>]OA^Y—SP\G Q\J9h랜zoXQԓR\Ե[k5bm#LX &YݗvHgt&ZzFx&̐c %9 8xrxZo6cO a,O i(tY-s̓sl0xϽU%K+[^r4,. u&ǽ4__CnťzYrY 6 ~f y}0ܭ`>Ö2dxLda4 /Se|-[sy辺GMhcTc%k,2$i,rmTpO޵w,D0@+W!~ڝmrDJJpFkĖ M7XhlslhƘmiVeSče8 eF5gd~C?A-u{GH]*֛W]F8yled_| z:SpRDB<}E\|6Tܙ Bd`vEC |t$=I3O2~Wt+4tF[ԑg Dg%'C\3Z+~4:dvW15VzN8b49rgW$b\q+ߵc>[^`8)u`9d]Ͽˑ?XCK멃_>a#>%N=Sc›|a]X2u3['Ԣ^ƙCk|]?ëޯn{{KhMHY0ArQ]d(>KWj<7eu[nGs}'oL|黦[a )aL7SE$!i$+MUs@c fdqՖzdNyj`8.y?9͘i'&Dy;:7 yBxv] GU-ܙm~Bl)Rm j%֖{+^Y0Ik&zl;O/mTQH?)d Ndb̳fP2y@85ެ.b(ڠ|fb}P @(P @(P @(8 *f|Nt+4f1LPj6K vq8WqA{;{:i^ߧf"d'FspM{VrV~g^Wb>{]I5kM%hF,%KVm21$jKV|8^R Nt\{"JUXg3WfiJ> ~N&<9>O9-NOqzY, Jz!f Ejk/~XZˤ^ezy+mP2SW&Чҋ%K6uI%dX!f`}TjQgYaӭt&Y @TE<>`rD5ƙ{$6ڒsFH<'R)G^B;:4cܶl򭟘5Q3_%н#Mr8"v#{:L}\w,<$$h 9g7:L E`6$G$V 6 A w|9<[C>Ek~Nf}9#Y)'ў8T:<3Kw{smAvW=8Ŷ̞;ZE+H _ZStl} rHCZC2K$NdcW ~=]\|R3Xϛ&)nM37cVe,v#Qo"m&Y#`wv ÷΋Yoj넣g#Ү:aT MO*!lJgX/8G'$@<O5UMlfNudNC~S\byΩtqLi/}`ȻԖ{9ل|1Q"빹eqQ!?*^2~+_M ;N?*^R~)6ʗT yzLvܿ =wɏk8a]/=Ys$jw6r{ݾuS+=JvJY󫍮Fc*MN-Ekm݌;XwDǤu;ǰtqd:fhaI瑸wSz4~{,,W/< 0,q972[}S=OoilXo#n;XǙ6b3\O>Ale$JK;_HS JO4RjZkHąFscL ,3eU^=oۚ8!g+]:\9Q?i`OahGPu{n `n2Zx5Nf-ۛ. ۔JpÊXdT9hMsn1X{MjFӭ!y͆`LegvO% 7_G} ݌TCB}Md:4K #I$F0d/ Ǯ1HI;'홵;<@0fV77,m'[&Fi̥AkĄH,Xͥ&w\qPD UI>g7L߈?*y1/3EZ}>Rfe^:"D'ԟaSemhzWm%"'ێO{g?]C >/k-nq-طߔcvrI9k}ئjdHղHR4g[zwYxjZ\jWd8m!0J&2* uΓKo~du9x>(n-{"̌Gܤ?;shok@tF[4wBOWh"A%$kk>(Zu^rwG0[mV1i=g[[}bqypf<2>8w#|vu M3,$* ppsڰ8m#RuK.YDo*!@8[jgdbA>E7N{{58*7qh^j͚DeKg[iw.:fOo$ l7 !sg>6NM,dLp2l|qKg+ 3b8OSmdG`Bcdmv>[9ټ㚍K2e";zƐBElv{WOo^y5~ߒ U_tkW{2GjP @(P @(P @(@a\鹸KKig>\H]+ 0,ǗS_Oé(mvBGk\g d(g://t$9Cp1{% rtr+&X`̃ٔ%`3籬Ki1[ lҩ90zz3VYHDdx`;f-ito軚LF[ԳV/(8\a;5~k/Կwoq >,sUA1~ZYkFgZ=HRW ;o=`? 2]Umqo=r\0\zVNԫQ]k'Fj)oq${DS a[<犏U4,>Kլ Ρyo&[|9'?ZwdY-줪]?J>}ާ#R j8Ѡ[e(XP=w?0[_Xl=͎!Hw>qg9#3ڴjXy5PO%Hd Lѐ@ [O<YFKzjH'#)ဌ^=ߟ=E+e F7`vWj0 7ULqSAQMgSRWؗڔz$_5!/~zSq)%%%[x;U8ֲa2L0L@{=E\g':^qC`kW1"zui# ]XKK:Iv:\"mv~isoV/*O،|Yͬ9T`9Ȩ'_IK}]6+4d6NPT99F>3i7ym lL )'|+gFQ'|x\=tvF*jǪ_(I V q6N0GaϭKrPᘤ|i; [RHUr ~G{;2nNhjSE4CuW'ՙ譹E>1E Db^WV:3MРm 6rzM6cn3ԋ8A=yDR>ʃTVF$o jqU娌$*g%p_-c ;-S&3 ɁݷMzy,-]Ͳ4. xROdD:t4۫jC$ HwrҵT6.N6sGw{gJydi"Wy%r{I$S'+\1P1>侊;ؿ*4p3 V?C7.pdw vxQ(];K O2xǙ0\:vr˒dE{S6VlXd}>))!/(d` V#`p{c cZJrzޥ⺅RQcتۛw R_y,vaW޹Osڵ%Mt:Hu dKkeH\O RT˻ 'x;xF9IkM/ KFanIB a$c{(.Y7kWBkO=ʫ ;k=HowaY& ga!V_VU9oˆ}__tkWrHR @(P @(P @(8 #ګA2EއuFx$T ;{U4ohxk< O*8'ھ{WJp|E?<"K?S> YXKNݲxkA>cٗWqL$2,vJ+{~5k Tt:[]l庁.mb.oI;;VqԚom& KR\<љ-)-R9e\{/JEVl5,nk'u,']"Cu]O$[c# M^Uq_B^Y+l+.ž-_J7W )W1 BxC^|w[FB~߀۵mtJm&GNYc1um8}Mp_3_NiyabPc? jjsc.:-֑dثNCµ76}[{Y6Dbʒy`&Dc2N~|WW'g~6MF۪䕴h^xULw߀>:\>%,E|.awF,Tqא*Y=ƥM^Y^KۄhHEcv7j[zcP 3zB$9ZKЩ%Y 2ʥ6F31m40˞pjZ'6~i[7@?E]=~kxż,HGa4>:VoueȌe !ⶺza*RIKobSM[(bVogԂi)pwMF`4S:D!?sPƘb'M;O`cϦ\^XC-PNX$H(#Mб8[urSTZ@BXû#>37Qͬ&BFFm˗cyUăz12;UMNj1gBݗe B >_M>r/뫤rXvA^F;^0V {!ssV:dP ;PTYU0f-lVt슌6C֖i%?Jj_FG^=J5#kپc0პyПlq?4cV (3ۑU/dO1/Scjb$9r"5'$*J+`P+=@REI=Ctfkxq[Ex!g"_¾2GjP @(P @(P @(@a\̣xm˾Y;0s~7zg/6Zo0xXk!d4źs.b6FxJ8KS8)u1I#> ew]XZ0tC+~[Gl G OU,JSz|FFM|+9?S]q"`xq7HyRܺ- +Mk_$X%pwmv?Z,e078$皃gɛ~cH:{6YgSµ^Wf1ڶê꿕5)$pJ$gǭQT`OR1YHrE:,Wp9V!LKyγx@ҮCI'n0VmMkFF3y&0;Q _VwZdWɂ` 1%NFcǥA^s__DѶ-^X`Fs%6cVN=ҽRBKf_m+ybH#8J^% m~Fl _mrIFFPs95{ü=),5w gɺ}-aZˤXc6!\]߂xttvNٻrlpO9սDb1z/?+2GjP @(P @(P @(@a\̡xsj;F'$|l1[}1qʋm Ԟ3kBHK}"RxhV2ʞn$`#?9n?sL`qG:8OwDY5-ERLHѝwa wx^OVIK)-XOxal}= ޔ#0 Q,Β&T|m,IƲxj9K:&-YCƖPOEn3"e7څ:Xq)2,C=={Uyrq n-м ?f0K #d}8sɶ0m"4ڣI j +}YѝWwOn(@T39<EInR1ȗ仵0X - drI* R0zzv֗P΀37bA4~,0ͮ隤J!\ 1qIm_I#g#ȱV,|ʮg=me`zF]!,>8e43hYA+’_ɽz:^ۭ-݊Vk;kq,fK\ߎ>2 zK6 $&LmTp8kHlvH@[vD0qҫCu5(E n]p>TXɯeg 3ɫ= M,pmow*CM<5Y!N#9%R1>SN&2I2Z^8@g9~U[9ڣbeK丼XhBI#9]JO(L犾FwC+e=RBM3kxzy`~>ubTbQ^*/HBCwHՌ*} cud죎 v8ǼI3=IOS>iNN>ҕo+8Iu;Ճ >Tv0>(]n#OjOl+/i`バ1޴oKkeRX)<~; T^c#MjAn{gr,\|}CQ?zrF}dn{gDes=jj/&WvnNӺJo4{v no$(nRA dk-{w_?Mkn)j5-g&/&xKp˟pq[5Y%EF]Ms-YJ-ˢF\qx$1N\,jцUN/ Ntͨm\#;wc<ҏ-_OYA<]U; UPYT,fHF]vq5mI>NMc]-b2̤<>wc go=zHc.|cW1<ـ1F$~QMNxFBJ}kIIYǡ幥-64HHěOyۚ^LBKQ£ @$zǮx/D{pfE}VD"ϡu,}e-݄q.2G~H?]!R?_]O<$VgYYI<˫. ҭZO6G$3U~Ȼnpvx$Ժ{eN*LȩW85%3)}-Ji#,KXYI]ۜ}0=Id-C/eay ǴJe%-.sQ[L(M0SyUQ՘߆(&':!RGǚ&>.& pdh Nio}('hǮrFk]MJ-g?b-E ( 0緯δ%SI<#C8 02sf$X>uXGepOl,QSu\RYRZ,pcIڸ½ӌ弞8EG蟅:ƍRL hʱ`%{F@;;]\bR{j7"$*x#qYʸe/{Q' ?g8ϒ_"&܋ sHR @(P @(P @(8 G~zST/~sev ((hd+={qa rwt2\~ FRWY1r[%cA8IR$uouMQg'1{|+O)гly irwQ\E26ܹ2JKk"OHDVDwnn֒mk^qFxԖ /{Ÿ̺H)sj2K(y h2>cj:.ЎZFWOɥͩxHYy v C>cӒsg϶}++rCϳM6 J0?HqN3/q6ҺX<ʤVzH-Yg5a [g+u^ͨ}$#WsN_A+ԥ]zǪ2]V 쥦iU }ܹ5CeF%V쥷U?[ a8ld3-{U2+Pʙ_9*`]Jy5~ ?]Wody!x[n<ӝiu7yN泎~ }D*$v0 RXU6gr3Y̤p1-%Oc΁XXfV{dH R{ѴMUS욵OlY:&y0Mk}Ol+5Egtb{1~qF3]UKn2~ڼmxgfU9P @(P @(P @p;PU\PA5l/m$G|l^yjǸa/.^,kpCһ)˵%Gt,9dR+i! ;w+ Vŵu9r4}_ZIෘ ft庫>9k)QC;K&|F?I+ 綰LQӠBR@|9Ab3ZڴdSX姆Ϻ^ɢ'_lE@̏S vmtN#ض*ϧH(*{pGT]1x6>&9e+(A3\KI dvl[wʴr1esVfoinTUCf*Vjpd=\{Mw%y 3[^OGMebż "d#0c%˻[ky= gvHE6 S㊥Yd7,tWHKkx;gqTz9XMkXy*Y($eF[k8s:65D ɰ׌|8b w2^*y auU9H8BN΀?W)ObPء=̻8@\;jy&ۈݍt 0bN lTj2u}Jkm4Ec 4*Gzcޠ(4"IVr␳m#*/LjH% AfHQ9PfלV┝\k)s;FvRq*+x#iu&uCg'.TylXdnx<׵XcԝK{*Awm(q8UK}WLӻbF(  |j1$ת)t=9-Z\w/u44n+l1v+ ~uV+y}V20=~uy9J.O_&d3:IdF9f`$}7(EXx $upSD<+*IJ*rϡԧ%QzPio}?ۃ#<9??uXRQIDwPbXysy*۞A N2ix!$iOb>wWd@ 6k5n-CH[u`ѯYP.T(@JtUA,GlDC4;XtD[$n^ |}f6Gđ\f2r/@ iDv@pņxGV4/1W EcqEq~׏ZY8QSo~HW?*;ZkFw0-α91Ѽ;:T=#eRj'4k+yeiBF +QsVRAiV[4YvK7@̸ }~ ^bЬcT^@n=&ZH]a]FkU2W\_,*SK-WRl;aG6ow}`㵴W㵳c\Ϩ]_Fd%59ʫ`Ƿ +{R D+ ^d= 9݇5zpoYmo$2yLv$<J]{8Ԯ㻩/1*", >_A ll䶬sԫ% }$#&=~;x53QK0̥ЍƉ|,_{~ OnݓGZԚlc0Ǘai};Iu,JAFDޏ拋 *rr{5Ӽ!&Jiűc'>Ա nIcW1 +ĵ6` }J[\RW=ϓf̖5UK99jf>S%l$7`=>UKPa?ci, tܰ`lw[صCV1 [ueHnAABkMdlkb<_+kcKOWzSNU_Fy+7;5:)v3(OS?‰J|WK;H en9±[*i ̞M]eUeQ˻x@''rj稊ܿ%^̶äZqo%l!Sgm?v Fm8;yFNsIVY ?je%D$w|w=;I',񂽤֑zb?Ek$dQ?X\ ː(}Tc'#=٫,ANci3dށ6&dG;['T#H_lK XP=Zt~M.䄂|\f85e_l.[%6fms.1STXXgX]Y-^KYYݕT0IpxTu+>(٦(в܏Nqi3;L֟F ۿ4cdeGkw,Ŭ[ f -ROaʅwfN}HHɂsc)6Ǿ!v:9mJ"ccy(8qOjvWZO k$UL`\v@y3&qޫ*e۾t$:E3ki:JAe\gfFG8Ze+g#h餮nʅ>B<=E,IŦY ;\c޷Xk\TzwIbiĪn-vI'=kb.qEj%7{crv69j _/'lZn)W! "LʹH9&1Na",{TgpOc{^Ŗ!HabWz)lgzKI4+W^ZK:īmAq ʪŚ3#o{O mjOʷYuy#/>~}~Ɠ[צ-t_` Z̡Y=~5hKFܳ||Qc ,LH$l2jP @(P @(P @(@aUs1@(q5ߌ:]hS@,!i918q++t-Cos84zdWNc'vӏۊn*|r}~>K 鋋ɇVu"2%+=}m.c*Y(6NK]OuNn:L./)Fth|j84$qi<,}^S@(P @(P @(jq -F]C/bH[xHۄe1PHHҰw=+R_jڝm~vxrʈ@JaT]s)c~r:}$ѿR}kc+w*y Jͥ6wz+SCc2l4stMMrx#_Ee^Kr"[*d+Aq#8ݭ$}2G1xO,z44M%Ĝ(${zwo18>U&s?FK^Ɵ<.x1HE%3ؑ2_X%=H|qq^N B/gDз$OW)((.x^p}[}=V8gOd k=Uŵ7Fxg7~1KO~O'iڙAcذ QK(2־%PXCKccf~LI&]kU%MA[:8yPP@A+c)؝%0$`dTI0dtVllo"#-r9l/|4oʚp;ߔ-8jts= {/'V}o--+Lq^'xy~IiĒ\ê^lH0 VF SRMʅ|Vyzpj!8;2;Wk;6Ÿ=>Hӎou\ cِ89#E_*6D()oΝ뻙5RW $z~+%NRRYz'3+%c^tomVb2IAckd8m2x s034~u;||Oo욚y.:1]n,0U/:4#cro-cBGUM)k1q^ mB[H"Rs멫Uor[Ȩr}Gּdv2J Js^5x:_::4mhtf2J]%bLcCpd,LX* 1Ts-ma~٫%њ$a7.c<`zJVWb[Q?=N>{uuP Ayj5{]a}04/8Y6 ' FĎIۙ'X$H]-SMAe-˜0|ߏ~+iN'%2,̊upH갰M|˜ڿEQ|d6hZX 3Abb;Ǡ:M}ԽR-7VG/g(x+,buM՚f8"a9w5h5kCm*詡<~f~җZktΩarŝ#I#oM;~hsoH@)ܠEd@(P @(P @(ƭg/!EGh`UpH;ٕOn3]67޽96hmWC_u[պeqil] @y*O|JzTRZ.xtdVn?M:V귑_4;s0;oMm4mk;j )1 /l|3wfݗVqȷb;-NҮhoeB7 ݑ291Q}No1LZtk#n4Dvb-槌*DS++wuMkڴɦFaPWϩҤA u=[K!gLO $3Hk$*bWk*Fs 8ٯY\im6qI ZS[FWÏS`hGHohI=>Z+˰KnYQfng"m`Gr13SSqr"h"\85E˹rMp/xi!e+{׵Yid8U{CzŜerD˪P= {rԫ e}?Sb,cyW0{Zj 6YMOw:7YTQ; xouO$?.]Qy7r\* HgjHN2Y3_Т1G:e7 dG=>5Л]F["!fA7PInHOaZĜ:{UtyD$mpX{J('5Xש8沊%dgmDVHT)K X]G7н N_+ךT{v0NFTKk@*1Ս4I%-4FY$HI=F#px>1лu `Y<у \Gñ[:Q|;u- 4LYvmƤJיd\%#&$jU(DM:ZGGdRU鑏k ͣ$#C+܉$%6$L[#Rla{p~Uy^2IԞAD+MC*,`,Lm'.Nf`} @(P @(P @(8.n&\Iy"$lF,kw][;<4xyu~(>x#GEiW|Y6^8Qj4ؽ-v]Wj+P;n,t/3lXb_{m}MvZzcEQ"&sv;Y "7d7 Tߚ꣘-PG >!ơ [SIGu#}5vKwsWMwoik r b<nw["&a.GR3)Hw!ܓ$HO_=v. [Խ01õu58J5ɯS)kvL[+'FM H56J!gctk}{vܘg8Gkğ$._.%,F%N_ qǭ\!%.1 Vy.Aq65gjp? aYr/'ei*AJrs#+ m2zԀ~pJeim3azVΟDsj7Ua#z i$sj[6gpԮtR=Jn%*q'9nS$ُBO`h(c|p0$ZĜwpl /_kqh1vI3urgQ-ͳz޼}+ ԟTy[o)-\Ǥ\TL#. nH}OQ{YdV/k&OMY/gg.*3}G~2>5$ac[R3F)*.Qr]َx犳X!Ȟ= Vsέl ?X:eǟo<˲PPCkx_}i'Eywv4J\FUqOw%¦#8?+d/=!v9߷|qVRwb`r9ek-H#6zT%+Y̠,ΫC?]a?y1M˼vd$J`jF9z/o&Aʧ}~f:'ڧo[l1>sAֵz)[;o ZJ5}NxO(Xݗ((U$hضGN* "Զ2,$"'p35ƒH9c2=ko=HY!O̾ =odnq ùVP n'<{|ζN;䜻&ѭK̒`(&4wKwqZeXKq]ٖHe*U *I@~{E@pf|F 2g*R<3So,2'YT\یEdCi}}yn-C|0}/\y"OX]Ktc#)l2jXM wG7^WzL=sJR0MR%H.A&?2"ber_-:k:oĞziBK{Xl8ct۴Ȩf|tmsvpS_N(@(P @(P @(],I?3^bYͿ&Lu?91韍U͹| &K,m~grk2k hD)d$>C!ivݜ}sRiAgw-,VϤ/I$1\s;"I VTR).uW]ZIK$|`v RF[k.uwtM9J &mQWuPN  |8wzSܑO2cC=䓳Cyv_I?HN|cGs=nEOfsyΟk3jb< ϻHl+ 9W=]h-`| xخj;m|/qҾpS@(P @(P @(UUX&x~ZneWE=0R9JHp2ASi}-O 6r׌^StK_iwk -:-6]'?uYOt.qgWe+wѝ5MԖi0v׶romWgRMk\ ✹TV 4_X di9±;H9v5k`W1[RH -&:;A;'8M:%gX$qCdA;6YGϥ$bYe2 `ҙF9G]#v҃Di.d.z('?"O_K~bykSп 8]:fL}~`[`L&\`mH'8 Y_ۏ+f/;Rh\IcƵn3dB,r¶-qPSxry}Bno 5 M.8 DJ0I9G UU+nQK%.ВKin$P^9!*牣rM[NvuQC/Z!^@H cygc4kKu<][ڗ*ե-l@G{''N9Iܢܱ\Nm<(5/|+ȭQ'}kE8[Rsj6F[kEI! ybO^eI&SVo+[t/Ĺ[z t%@o/#o8>+41NUFeKy?gl*O9!dVbs@b"fqo$cg~?vdzqL; he1MYI'i|~uv(,X^xEukIϴmyqiFfY;>5Υ\^Myj%mR)79RS=*#&3ƅ܄EML'gMٸ)w6U:t-6y'9(!Iy4 :$-B Sp8+ n# O_JuԁI%8P͝ X8ĺUvwPSj֟b93 y1Ho*wy<Ňe0zkbs! .>ux^_?#c/&FaiyUŤ@46{g^JtY춟)GcҐhn#xLG^q=0F*JG'Qz>N2=!kd7`ZZMQmΉ ՉΝ(+kgA(dm<.N9a4H4%6Osnu~T:Jin\҅L=t}kmn}^\0TS\,QHhP @(P @(PGB؏r=|O؆GBQ?Sb8klW M9ك@J:rP-2+9 X[;$<ou{]}x 9žS -4häBET\csm۹Og8mOe/O;M?ٟmm%**j/2vK?wyOjRcC_=OY/~5YP_ ͭ`1TiI矉n?Z#S PIΌYn:˅6AfֶĎ^?St/_ [1sxV??h53I(S+V+xFyOαi-?$?hXpq>?Q闯gQ?Gj9,ԡ6 }OέUz=$L&wLVs W;nGCSz}T4{F;\Sc>};}imZg7{2T5o|/e/;#R.9zjKyר0I\@>_=Os?+?#5R'^XQqAifcA~'$M]7<_ZLMnt48kcnIGb/i?P~Vyz!ًO)(zz#~xZ3s2+{0kTi"ʻAG'뗽'}^>ېG\sJ &2lϧU~;}f7St^z,GfA[t kGTfϰ*^ m$_Z&:<d;Z9?o91ԅna)%}e瓟?CgiĒ:k_L~Q:ML;?:ǥ6ȻNk0(>RYȗ(G+%IC1fRք9*?joH__c?c>e`f{V_`?u;[&ʬ[>7U#X%>$8?:#J(cO:|#xd=_=J/Nozzޡkoqh.B`W?*uɽDZ1=2mM|V,P @(P @(P @(@s@(P @(P @(P @(P @(P @(P @(P @(P @(P @(P4P @(P @(P @(P @(P @(P @(P @(P @(P @(P @(@s@(P @(P @(P @(P @(P @(P @(P @(P @(P @(P4P @(P @(P @(P @(P @(P @(P @(P @(P @(P @(@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@;Prubyworks-ansi-291cecc/docs/assets/images/github.png000066400000000000000000000374331516262404200227070ustar00rootroot00000000000000PNG  IHDR\rfbKGD pHYs  tIME jN IDATxy\Wu{[}J%Y,[my6 6ʘ`C1raH7L$_.||_ !pI<$ *`yQ5XSUw}NթRw%uzkgwk5(*zڬ88 X,~X{y!`9[v[ݶ`6 Nˉg{GKQkGɔ5X%ȔIv`C #0nnjJAJE0k֥I(^%k_5X-XYUJ`aar\Ժn]RſFҸ/Nf1`#f#cXrJAUJ5̣i'@C,OǼR/EE܊y?Ⲵl |.e/FAU18 j:BfftBkMJ?*s'6@~!ZW ?_fZ9 @j|!E0B8edT~ E".KIsbgPZc)iˁ"F( ï둜-;ߔ>UkM!c i 2kݛ5G|NG ;6/]0]oo֛ ,?MA'.yQ&`#rP?*޸P楈AkWe pG4 ID_@J?9m]ǜ(n/#ng!C[s/RNT(-B@#W \j{4g`{D/l3f ]| zcA?xsw[J&g^E=N+(Q%0<(𑴜fs/PsK>W\ x%pz8*F06H|dZN~#uJJ\ 86rA;~VJ[}oSJ!Ig D-JXVڍI) J\Sc6_Y$o ]c `Z,Qy?k2͐cp(v飆O ޑ]s3Ro.6zp&(=ȧyOZI("L0H tQzLit[ zUR5h?JomJqN9,QKAMMٖ\?X 9(sKo֛O#j2CEvR,!j4QwT덿6)-'=zZsY󿱭2gA@H# ^ ]瓎K_!caξP?pWa``]o1ҏ(@G1i%tO'px= 1eBoFZo.W)H\`.iOү, \e[)JiZ \odU}S!QF.cW#^_7g8``)~@RJz/ 17'p^ͼw+AoWL2.A>6f#FB'Q"`kjy5Zoŭ +Hj6-'ry fXE>bF"E2 ,x)mJsЩ0:acDy@#X|qlˌL(~? % 4WGtٞȋ2~; 0'z7p\`3{204ׇ&0l5EL2Zsx{<ɧo֚kfmg*^<3R58"C>;2!.|@_x^\`z E\MlD6 wbƇJ: 8RfH)NQեai yTFH[AoF5mZ=/l? |{gB+qq/!}->ލC+B PҼXm7NW]{VπE~h=Q@ ?b}yy*xxlKmitW>Bz5fwm Nri JLӁg , V6Ѓ xE`Ԑx0COd_gqonE{}ԛ7>JB<qͯKH  nqۈb r Of Y7Ӵ >K_t0?6s>K#Aqp̧/\$RItO?rIc-.Ͷ*=׷hۃ{j˜L4S< 'tuqنONǶ9-'H ZokIϷ9_~L:Zˑ ݵJiۀ!nl.7`<1o~ 1;2?QfNz c?tD2E (Te/l]<_f28nf;7WxS59i983Ț,3-Ho:7F4'B}w mꦜ rWCZ.=\\^7_~3G= iG$醠 nF@(Ҙa$cD>vbHݔI;f 9)rkZl#c 6IϢȍm4$x"j@ZNj ˲=s;j}%6Oku| V|47!(TPZ(p? 0 i#h+ ll! , 'G>L*jJ`aWmGw:"[ZNvNubhY2on>Q8M~E3Ypw5)J?*S[;{;GFF|rm1=.R]QP2AC, 38|D S}ddcf4_VjkgtU=xfQ;У[y{=3rBZIF{旀m؂8Zchv[5~Xx h1fIE`&-lz hB Y!@VZo u`I+?U௤Ҍ7mۏA&Lŭԛ/5|O7bLjO7 0 <`IO"[]1Y!l =k$v-$l(pifZo?=0u!Wa G_U2\8 +{`t8Zoۛ6g|*%pcD+˱p*b_a0TW?&FyshoR@/#;1\J+<\ٮa1lV덣@M HƱsGwi`yN :R4@-3Кe%JYY7v,*40ʟqH#0χVc]bംaԆGQ悌I8W݃(RUxBe̼z S O>Zo>s ՛CO?P6#qޖB`.Kd ҥ[YChZE rJ 1+C'GmԚhOKzq\4- Zo"8q\$b6O>gF1!g p,@<sT܀I6ZQ r1YbRWھ6n0e_,G>/L果`ғh- okh{W9c{48n) G q&pNb&_vЃ/rre P?W.yfP S[ٖJA, md]mbk6>?|jXO*F<X=Up}%uU>V|Hc^n*/<ܞcE LЙ֡Ii0%ۉ1GdGXFT9tm!2 ~k1+g Ѕcoy1V׃V_5@5RwAs%Sf2% !E:ap9Z9/K˥/&*\QqB@y&{6-O:9qNj UkՄ&)ǿ|/O_1A ҁs2d,!#+|Qa6]#@ | vI Z欫x/+zϞK+GH5jh>m% 0 |&-; N֚+P g;5OE?P+'B>mt"Α)/N+? |/-'ƣKQ> 1p]ҝYk^@{Xbوq l`^>^a`($뛘mQ]=%,1<{7_z [ȻQ2Ji%9}V J>k1嶖ʞ8 ? ֏‘H (-Hs*|z\PpFˁ'ATmG5wzہP18>Ox2FzS \Y$`&(QS@;L O&3B@Xs?6o3ZYHqaZ9+B9񰳠Piv_8,1Q#C /ik8VC=(DHu] @Tx7ovwnc;\x*sB{ۭ#ltIo-P7Wv @xXԅA?R8n` hE! JghKTAtJ ):hg5=kPP((f𶎨P_'ǀZ#·1vlGM,){p7PN% +kW!.FTA b߷ihE8.2셝qK#CL`Q  G!2? \ D=jyTT ǏSAWFb6b n(nmԸfaX+ c0O.qEog}S>"o??{bIV.+fᨽR0w| zN'?eZ휍9 {Q@dzs8@C'[=Z5cx# *P{'bP[]1G1cQQIcYIcvn{rc  @O]\J`FZl3⽛-i90O|BCe` Xކ8 i[ZNvnAz0`10/{9$m> h2J1Y#\jq\ۏHf͈ۀ;QL@h#B6h`f!r)\$$h$_5 ،HjfF8̇u SW8m"5 l6b7۳.䝠FN0%dhؑV/qS:am|Zk7hw  H eBHDZl6@gB|i\b/J ; B@Q]ui1{,; #m^h xq;-b"Vuo]bja|"R'-a#gf]eZ.Q`VL76л%"&?nEގihf:#lԛj41mpbyZo$fʟ],X\{7M&iXX >8taBi7aǰmzr,RfG{k[ wv G yl0IKyY'%YÝ?oml Ǣ x#HcF&PGeG{w`! vNQh=M@jEUO88I )$4- e{G#Q`#&+vbΖ)fDd,-'@G[AYXя*RB.֛O9nі(2vx\,.1Iy 1"bBzPZ#ws 4{)K7wۓ`&OC~xGRz,\m|%Lb1=eIDDt6e賰:{+:!j{ZL J/Z$Wa.6:/IDAT태gpma[b 0'FXmJwjyn\@*9x+rWq4VУCi91en28 PhB晹/$DE/*\VAm7 ݊x4c<"8Nd#g >zA`AZN_k ~pLW/`+WL[7ukbWaqɻD-G )Ss$iX-zb@dg^爿N)7Gh~Vi9yZgh jI :Zo~)-'?C]@o߀5SS~峰6gElHB1,jH~=ZoqZ)_f2}_7 xqIqźP#jo^~9#:Nf1sڄY/3jU6ۻzE O/ezfvY; ρt(1pΛBCӷI:f2叱ɕh%[Uv pݐt{-GxOWb>52/|>RCr ƬNʿ䪐n2s WY\U+u*k]"K*g.yCJĭ:@|_+U ?/t)f!D~& %~܅b]M ]O=xp6xIN+*~ȥi9xp 6]J;x=4lF<|`q.1+W;M O>rW m%e|f8VLe l~IZ)ZkVf;impn"mL Q| \}_vMcZf~s]޼5dS Dg@acϮѡ˺XuZٳX$PB8A8bO#ݠo'S]IJBX8*Ոhgv6ϣ#m;v[[) u94pB8)s4j;ׅ6|zWu{l񳴒\g"u2A)8K=*?3 =(ZW'n0c3wk5g;Dbݒor5sAxTbK5qҟ1-'۪FHAZN6!>t9*6*Q42"6z\FŴg֚6nU[r--'| F-]V^Ul~zM`htco1 [֚"><8dP$} #0j*;x|:> \ն[JI}w#M;[;tkZNFe`hTCIr攴\ڕVA/BI˥O 3 t7ϥҮvR.ha_a?=cMt?n/f7AZ/.֛K5 A ֘_H+tM!m`ـ{TWaͱE_R3g@ZIFc?2P BE^Tͼ)-'V.?Hpia58h;~]^UkSߛyg{- H+%[ @u>1 >vZk|x%1ol#s;ڦĈۢr W;]E"pcjSxIG\/lI^ZNvoG iGW\8 |W6aNza{;Eѝ.:3-6B]Gl,Nuq lmn,VUkͷ ~ Q`ב.J)1Bqa%2%lxOuaF9}ooKzv|kPcM*#Z'ݲCz b쳀%36a3+KELr6MMmf]a&>Gc`ϋ3br7;}{oV+1k7y֛rr~n a}E\xU ){Im <W7o>)d3%#[@7L yyZ.m֛WA,ʅ5^Uu7"> lϜj &37n/`Bn R lJl#\L8=ďnEݛ]@_ͯN}{ BO~Z7lsKn xN*i_nT˵xǾ䅏Y^Vz(z f' g?ΨgYVKHÔi+y`[1 p&yOwD]BI=!۱tG:ά}”ݘ+>l9Cx,`%)?gxRmtg}o^oAܩՊ|Jpгu(Bo%a$1EjN&&/3e*1q^R5UKIc(QKJioy]`pk޼xnh5Be>3Vk!5|WLU@$*P!@/ck?ܴ/14iU{hp_̾!jjzJz_|bD鴼Xׅ}oucSr yT mnO4Zk>lx<་E֩duEĽ݈/K5'->9?+oUd[}2gma4TIBQG(f7WKjmcL,偬-z8v}&]R|a0Ç/AQlS6#}0J~o7[?j~`[lkǔEHi7r}_i ۋi%&qp3(qNb_hGܧQ9y|n -LMFサFQDB(`з4cl:bD%ʴɖR] |=$;r=#.oZ$ۀ0:QL=MeEV~b qY+?J!;`o(NR#v$ D&~S@Ofȓ> .gpQ>|pMUjSXv@.@%Vhse! (eD90w!e6$= gV9̏Ff]](Qg@Ʈ,+) jx^A@%>~?~ތs:{JL{yZN#o͆%>?ʛl0vD3SR;CR0d}b( Jyi@T1ZA D2nV.9?n00aBgj}@";-'_ƾvCzǥrؿZS6y]衙S /k;'E6;mf rB֠V)p_F1 y@_~ :BM' -H|,-'mh+ey8VN|bn>kkcxrS:h `~'L*cEr{WZEǡc c2NLi,\@C0ۨl>" Bb<`2b.7'V!I'x* ZPaZ,ه9 Z: X}Ǒ&0 vSi%Zk!23O&Jr擄"Y#g$0cn c_IC '_s~>XվnVxV\P|O6J̮0_DHҦG%J [ NlM%xAw5wLy 9J`-~ B+xi9jE3o1bViHDlZ.,^B?ȣ_ՑenRWƾہ2X}$ xGZN*,8"_RkCzවt4O[bޙV k0| و߅y'i9ydOl%t @Xpq5l~, ::&;%$z04^{M{r_ zc7ҙ<)_> Y!—NZ࿀jyHy!Bt4Ag^ߍ/yBu."rd0XkszCg /,r^yV'Ro#?hp\LqHyNncCA <clq*͔lA(xp4ׁf136F9kvCpe5_*+r]8hqLT3~ZCFBA9#cR<`F ϝ?kLLVߚw(Xfv,/Z4[g/_j T٢=O)7!p_'Wo=`VU(jc,wJz&i%g'߉le pYܯ?>Tj $ͺ+WZIZi9)`4ӆW!ߌ td؟Q4Qd4&פg8u8$7 `# 뚟mG;s2й@MI+o^RCAT~"հc*J cJT<ԚGI 8gE 2k:o|i9.@@<iBkR($\TkͅRB`(<R o侹-' HI(]^SkJ}@B:&b,FCjw`0>W r,~{3Fj61tkG`QogW{B1aX z#X^0!YXK5kX? ],F0/ƟuHmy|ooVN3tȯ"?tXB540߀:pYRXDC \b@,Bסen"Qazeuf_H|\1(T"gpZN.(spC/eЎNlƍ ԛlN^(SYak]dsa_5|YZjA;,gJ<^szT A{@unKI=0 KC:JkylwwCfZב^`Y /T1G" }ʔ93N! RF(ӽ5Ji2P@c0/_LAanǎqwg05c_| #-'ѷ7Kz+oct-nJ&J ۄZ#Ahܿmn;_䁨jنsd?iI eQZƹl*ұq 7_u{ZI:}ޤ~F$<|8AZa|:i'K: 8y\LF6c~A)7i%D򣕊 oL|]7/:qp,7q1c.( <]wi+]^JgNFxp`C[07K2S?BH$ G^ :Pi9fR` 1#]֮f z`#i9:ZJ ^Zk  Ñ!+Gb 4u0 ۰7 փE;i%*y(j!*18dJW e~is&?kّ zNjɌIENDB`rubyworks-ansi-291cecc/docs/assets/images/logo.png000066400000000000000000000256611516262404200223650ustar00rootroot00000000000000PNG  IHDR +sRGBbKGDC pHYs  tIME 9qB IDATx햣*EyEݤ ) Qge|EYXk9Rw-h $ pQ/8Hpt:S ɽ6 ]@ t.],<]@ t.]P0WfmH{Ylseink?m'kMxl1ҹw~/]8Gq9k[|}2vL `8gG XfV J(jڹPŢn|m+%"ן EuXz8Pǂy^Zk7. tn@A(bc+IJV;'PL $pS3ZM$5Gwߢ pptqt-].谺ۡmFkEf>\lMuha fGn .tk[. thlFֶ،@ .tk[. tB-BWۭm<To~2 Og|:gqƚOM?ojf)sf*{2j}WPqJ|Ji⟱ДdX ВTc%s]̽]]$yQ+ q(C h)w$$Q[$p?[;>CN˸^{$Zئ;>!%k(.B.W؆bՕ\?P $!&NPDZM ^q! YւTy^/|.BnGGG _(XmA .B`nhgN [BnL}X UW(8gWU8 YWS'tU2/Ͷ]J(R _osRf 5 e8 3 GGGB p5d]u9+3YΓu @ .B p/K]¾ ]m (r$r6k7)=3μ\]#f!Xs.}TJ%iS9:'ʦS-r}:)K~NQ=*@|ʚKWg#'KBۓ^;0B_|d 8f6'[R(DRL. I 5B)q oY ]S\J&?_uSB}*;̓渦(1JǧK.?%|V'=х- BNkB]@'GB ,Z%QxN<M)8-nZuWƢ!Ư ]5RhGWͬ`ϯzI0Q]! HJX3 ]=!tĺ&tB69!-7B ͱ}%ta8 s 'A8l!{ɢ5w8].@ BOȣ{b]G<7jC))5LiDŽҏu]}Ѓڨ Tn\JD[L9cƽŶ}`~;OKE[:(fj1Z;cj[Ƒb>9δa~ׂc~DY;@%Y j,ɱ Io^ZaB80BI$?cv'tЅ1.@Dv/ŧTҺDXj!qBGG`|3ZjX@`\ؠ]Y& fUh Num х W{MB!.,BUjݾ]^|J);IG/ ] t À;0\nS*OiI",8z .U=!t/BvCB~"t P=Q&.ЅŧTҺDXj!qBB0E_u 'p0~^wQRinE x'gNiJ>ӱ0>Ab!;-mo!h\zڭ=rtyNm˧%cq]*ϙX^f4p8н+ֹ/YBgdP^z/,BLkQr+܏ȡZ3w|Uϛ~gc ]}rصfF9Z#EH\[1EєMM \)FUی3w|ͧ{9aqN Y)7CǟcuX]PNnb{ȏvGw 0fEeڝ(̺ZJtwh#A&m8 U9WNeb\ 03%tp&t{ PNnb{ȏvЅ!3 . tqtA:"?}!3..h ij!4AL .M3&xB@:"?}Blτ.нbRE&'>nYptl881EK+7v_㔛:5-yȱ[5[% Zqx:Zr^Ҝ#^uhZk[.mսn1n TۇZڏGZ}S0bNm},[rȗ'~ϟ{ny`æ͹;ԙ2y?VCBf^+zX}(0nݗ<گ<}OrOUgʭG H,+vqZKB6O0 y9ta]pT_Y@>k[1rFqti?Gq]k>38g+ tNa/BرҒ6h/ ;-}zlRĮѷ26D&p8tW7uW'),U?6諺n8r\IߔBzm*1>k͌1fY뺥^3Wz( ]8<@Bv" t5࢕! C6f4@vw@،g"`3kIh#=ByG\-<OB] tA3B^cN^.~گ9 . ]]z8I@9BϳvWZVL8\'i]G7g ,%͖ݶ} /FשuLuZėY?׸RyH5s.$VG/i9RMuB!Xh\Y}ҮWC־)Vx '|cx*}R =guDlP e euиng{]>m(v[ch?Z72Cb1г<}Vѽg]vptqt'3ptaȣ H0BV4>VPVR=ݮ .L 0 S nqDˀ{-t[z LsjR&l yM\nbrO;칣\ْKiO}:ڬ Om{nz놙jsTGȬ R>pV(=K˳7cҽխT8zN. t7Yu6NCɺݮYȺvxb_  tر ]gB"tЅ B{8U8zNf(BL^;᪱6X\:/)uOk:-No2x7%V/n[GFrSn7YJ~롕U&WRHo5fKUӞCzLӫ=׎O#{_-q3{äe9qO +̅M)1kLWbx-ґbx5-"㺌4gi}ehH,U_j*У=-c CƏ8^-t׊^oRw&36ūiJE(m}b4, zӣ==";eX8{ Zm3@ kYIB zC@BЅmC!t@ %4 .י8B`>0ӊ6- ђafK%fvelӖ^}rc*4'L,_u]=bAΦ'ttK03I,|>ZǸqbo1vjϹ`DCFsp%7j9lG>B+-ّ9u@]@B]ȖЅ!ˣuB @N،V2@huf{f3\YQf4@N.n^gg]8]@ t .8.^ggB]ٙ&Xܩ|g-O1=G$ucVm;혖nh+G:7p;4hҹ\dWIZےژ3/~=cRHIk?=ab#tЅID EKC.ShOS нp;E[-_Rѝ<6 $]TAКYƩ;MoJ[@nSvͫUvg/w׶\-~rmHrpHy>U Ѕ!W̄.'bBJ) z ӟvM t] taGBQ ӔD t/\Nqtԇpt)1?r|>MH8@ . eKC.ShO5 hb#tЅID EKC.ShOS 0"%)RYa>yt.I%ҐgfK4t1sbS|sO:n-)(Twҽ׶Ԧ[ٴk]_Ɩ߉ų:j}3'[}$.Om-gvW~c-ô9{o|._ Y1*K iTSnܚ= xIpЇf *)1 s5m.-PԦn~9 э%IJsЅZ-5_~|EиzB6̆}hРk_ma3Bkݑ?-ݱV8c4Mb82flGd WJhZ&mSrqFՌ1jrm{wڌvEuY:ZjٌwIwkhWԁ/q5n[zZЅ0.p%.mhmў،6Bkf4@ t!Ѕz]B]B]@6@BD!tЅZ?B 莵zӥmm6-f80;CMֵ_Xx5OIjғВF-qĞ])]&_9J)Ŏpvs$9DKnv,B#W,RIbyozTȥi3Ƙe~ޢԮU_ZVMI6]8R"r_,Fp׬{^؆"wB,PRJ\pB!R?kԄEBN@VJDk/lC;t! HBO%A)!+ 9}qAQЅm0qtw&Uoq<wGB] t!)68.tj.\SLmV6{8+#C.twCNLkK/ގKW0YaH햏'K>^:Pw7d]- ڭkJ*H8<.ɺ \fnocvv_R{<7cj.Zѽ]]ܖ۩^S tPYȺ1K,K]d]B] .i.\S t788-7qtw1);cg3'% M ?\I>_IC$kIU ϽӤUZS-/w|M=f̱RI}i߇%}$Z^)mRJ;% {gYeq4Uf6S;icSJc ..0>AJTv7l7| PJMyJ' iIM>WH AI}F_E"[=S b7Em1^v1<]NT$b:>ڌmI `{NNkyI#5HgP9bWNJBUɍ|P`uoKwhm)OvǞsyZ6B۶jN:Eki#b (@ C@. c.8j MnB.Y|Ѕ tanyvFr;Hpl 22f[&X\ܯ߱e4طd]]ZQܤz<W.n\H7+t$B8vn+EGօYuTDd]oU["tS;ANx vGgo`] taɊЅ7. cf]h[6!tha,K`ٌfKްm,،6f4zE"taV፣{[6c<2ŴsyZ6B BFЅ?] B `DƱ(Z &M K{_qzhz#:BA>6,s˘%>~h$$۵r`v&}$ xSpB s߿Kcyl?sKdb) ]iO' UzX ]4˲,?.Iaˉ\øœ3ΔAϫN{BcS.1<)ѱ=nIYjne*:0f+}l&K~b/￳8~&>OrZ?Rq~jjǹscBut*Y;t]n#1)mq;ݫM, 0O ]8-}O2Gd_7n?c1-OmuskgoU]Jǣ9uգ]kb>n*w[ǁ%tzE't ]x~HBB] ta8_yptqtqtqtqtqtqtqtqt+ϿB1-]'s֯#L2Lh;5a12fG\ }Kev]^T=yuzrjl`Jf]G{ %IDAT|ctЅ.mC.z ]wG89WB{VB]S^\N_ց5cر߾sp~&ǭNwu]Tsr#cjǼ\[\\G1,O ;6]]4 =\PBn-t-B*o$O ]B@!tЅɄ. . t%C.@y˃E"<Y#!tGWBZѽ@1.Q8.J҄.'t ] t'pt88]]]]]왎nx2xnM[ΕL]Y։ZGA'/˘%txBD]?K[{<*Tj'jBR(tnp\Nѭi#1-> R1>S1%xwv9q_YP+rA;%( υ#|^;9uq㉄+E RO,jxlȕ΅E(cLMy1{ǩ3uhjRDiK3UW7Ǝn|_Hj&C8)60>+M a/Jc!EmJέc)OB<>ꞡcFUGGw̉x۶{k[=xmFKQ`fӒڌ0^jnV4wfvjfyAWt]겈nmilFc3&ٌ֬ ]!tn* ]B <9{Li'v%IID=z/;"\k޸)ku9x]2$W0= $QH>}F|`n6ϜϤkN7 >9LL(,.}>ּ^ OMM|%꿏:/T]F$ 6VW))t5FKòQq"rf y_Oa| pHJ*MTX8[^Dr-||[v(33!.44NJebʡrטu͚d+@ S[Ko~TKrjkoraPDPy5@Y?i܅Sg@'˼Zj_M5̻w. ;'5ڿ_IENDB`rubyworks-ansi-291cecc/docs/assets/scripts/000077500000000000000000000000001516262404200211275ustar00rootroot00000000000000rubyworks-ansi-291cecc/docs/assets/scripts/highlight.js000066400000000000000000000633501516262404200234430ustar00rootroot00000000000000var hljs=new function(){var p={};var a={};function n(c){return c.replace(/&/gm,"&").replace(//gm,">")}function k(s,r){if(!s){return false}for(var c=0;c'+n(N[0])+""}else{Q+=n(N[0])}T=S.lR.lastIndex;N=S.lR.exec(P)}Q+=n(P.substr(T,P.length-T));return Q}function M(r,O){if(O.subLanguage&&a[O.subLanguage]){var N=g(O.subLanguage,r);u+=N.keyword_count;C+=N.r;return N.value}else{return G(r,O)}}function J(O,r){var N=O.nM?"":'';if(O.rB){c+=N;O.buffer=""}else{if(O.eB){c+=n(r)+N;O.buffer=""}else{c+=N;O.buffer=r}}D[D.length]=O}function F(R,N,S){var T=D[D.length-1];if(S){c+=M(T.buffer+R,T);return false}var O=A(N,T);if(O){c+=M(T.buffer+R,T);J(O,N);C+=O.r;return O.rB}var r=x(D.length-1,N);if(r){var Q=T.nM?"":"";if(T.rE){c+=M(T.buffer+R,T)+Q}else{if(T.eE){c+=M(T.buffer+R,T)+Q+n(N)}else{c+=M(T.buffer+R+N,T)+Q}}while(r>1){Q=D[D.length-2].nM?"":"";c+=Q;r--;D.length--}D.length--;D[D.length-1].buffer="";if(T.starts){for(var P=0;P1){throw"Illegal"}return{r:C,keyword_count:u,value:c}}catch(H){if(H=="Illegal"){return{r:0,keyword_count:0,value:n(E)}}else{throw H}}}function h(s){var r="";for(var c=0;c"}function B(C){return""}while(z.length||A.length){var w=v().splice(0,1)[0];x+=n(y.substr(s,w.offset-s));s=w.offset;if(w.event=="start"){x+=t(w.node);u.push(w.node)}else{if(w.event=="stop"){var r=u.length;do{r--;var c=u[r];x+=B(c)}while(c!=w.node);u.splice(r,1);while(rD){D=c;var B=t.value;v=E}}}if(B){if(C){B=B.replace(/^(\t+)/gm,function(r,I,H,G){return I.replace(/\t/g,C)})}var x=y.className;if(!x.match(v)){x+=" "+v}var s=d(y);if(s.length){var u=document.createElement("pre");u.innerHTML=B;B=m(s,d(u),F)}var A=document.createElement("div");A.innerHTML='

'+B+"
";var w=y.parentNode.parentNode;w.replaceChild(A.firstChild,y.parentNode)}}function e(s,r,c){var t="m"+(s.cI?"i":"")+(c?"g":"");return new RegExp(r,t)}function j(){for(var r in p){if(!p.hasOwnProperty(r)){continue}var s=p[r];for(var c=0;c|>=|>>|>>=|>>>|>>>=|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:["escape"],r:0};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:["escape"],r:0};this.BE={cN:"escape",b:"\\\\.",e:"^",nM:true,r:0};this.CLCM={cN:"comment",b:"//",e:"$",r:0};this.CBLCLM={cN:"comment",b:"/\\*",e:"\\*/"};this.HCM={cN:"comment",b:"#",e:"$"};this.CNM={cN:"number",b:this.CNR,e:"^",r:0}}();var initHighlightingOnLoad=hljs.initHighlightingOnLoad;hljs.LANGUAGES.cs={dM:{l:[hljs.UIR],c:["comment","string","number"],k:{"abstract":1,as:1,base:1,bool:1,"break":1,"byte":1,"case":1,"catch":1,"char":1,checked:1,"class":1,"const":1,"continue":1,decimal:1,"default":1,delegate:1,"do":1,"do":1,"double":1,"else":1,"enum":1,event:1,explicit:1,extern:1,"false":1,"finally":1,fixed:1,"float":1,"for":1,foreach:1,"goto":1,"if":1,implicit:1,"in":1,"int":1,"interface":1,internal:1,is:1,lock:1,"long":1,namespace:1,"new":1,"null":1,object:1,operator:1,out:1,override:1,params:1,"private":1,"protected":1,"public":1,readonly:1,ref:1,"return":1,sbyte:1,sealed:1,"short":1,sizeof:1,stackalloc:1,"static":1,string:1,struct:1,"switch":1,"this":1,"throw":1,"true":1,"try":1,"typeof":1,uint:1,ulong:1,unchecked:1,unsafe:1,ushort:1,using:1,virtual:1,"volatile":1,"void":1,"while":1,ascending:1,descending:1,from:1,get:1,group:1,into:1,join:1,let:1,orderby:1,partial:1,select:1,set:1,value:1,"var":1,where:1,yield:1}},m:[{cN:"comment",b:"///",e:"$",rB:true,c:["xmlDocTag"]},{cN:"xmlDocTag",b:"///|",e:"^"},{cN:"xmlDocTag",b:""},{cN:"string",b:'@"',e:'"',c:["quoteQuote"]},{cN:"quoteQuote",b:'""',e:"^"},hljs.CLCM,hljs.CBLCLM,hljs.ASM,hljs.QSM,hljs.BE,hljs.CNM]};hljs.LANGUAGES.cpp=function(){var a={keyword:{"false":1,"int":1,"float":1,"while":1,"private":1,"char":1,"catch":1,"export":1,virtual:1,operator:2,sizeof:2,dynamic_cast:2,typedef:2,const_cast:2,"const":1,struct:1,"for":1,static_cast:2,union:1,namespace:1,unsigned:1,"long":1,"throw":1,"volatile":2,"static":1,"protected":1,bool:1,template:1,mutable:1,"if":1,"public":1,friend:2,"do":1,"return":1,"goto":1,auto:1,"void":2,"enum":1,"else":1,"break":1,"new":1,extern:1,using:1,"true":1,"class":1,asm:1,"case":1,typeid:1,"short":1,reinterpret_cast:2,"default":1,"double":1,register:1,explicit:1,signed:1,typename:1,"try":1,"this":1,"switch":1,"continue":1,wchar_t:1,inline:1,"delete":1},built_in:{std:1,string:1,cin:1,cout:1,cerr:1,clog:1,stringstream:1,istringstream:1,ostringstream:1,auto_ptr:1,deque:1,list:1,queue:1,stack:1,vector:1,map:1,set:1,bitset:1,multiset:1,multimap:1}};return{dM:{l:[hljs.UIR],i:"",c:["stl_container"],l:[hljs.UIR],k:a,r:10}]}}();hljs.LANGUAGES.diff={cI:true,dM:{c:["chunk","header","addition","deletion","change"]},m:[{cN:"chunk",b:"^\\@\\@ +\\-\\d+,\\d+ +\\+\\d+,\\d+ +\\@\\@$",e:"^",r:10},{cN:"chunk",b:"^\\*\\*\\* +\\d+,\\d+ +\\*\\*\\*\\*$",e:"^",r:10},{cN:"chunk",b:"^\\-\\-\\- +\\d+,\\d+ +\\-\\-\\-\\-$",e:"^",r:10},{cN:"header",b:"Index: ",e:"$"},{cN:"header",b:"=====",e:"=====$"},{cN:"header",b:"^\\-\\-\\-",e:"$"},{cN:"header",b:"^\\*{3} ",e:"$"},{cN:"header",b:"^\\+\\+\\+",e:"$"},{cN:"header",b:"\\*{5}",e:"\\*{5}$"},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"change",b:"^\\!",e:"$"}]};hljs.XML_COMMENT={cN:"comment",b:""};hljs.XML_ATTR={cN:"attribute",b:"\\s[a-zA-Z\\:-]+=",e:"^",c:["value"]};hljs.XML_VALUE_QUOT={cN:"value",b:'"',e:'"'};hljs.XML_VALUE_APOS={cN:"value",b:"'",e:"'"};hljs.LANGUAGES.xml={dM:{c:["pi","comment","cdata","tag"]},cI:true,m:[{cN:"pi",b:"<\\?",e:"\\?>",r:10},hljs.XML_COMMENT,{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>"},{cN:"tag",b:"",c:["title","tag_internal"],r:1.5},{cN:"title",b:"[A-Za-z:_][A-Za-z0-9\\._:-]+",e:"^",r:0},{cN:"tag_internal",b:"^",eW:true,nM:true,c:["attribute"],r:0,i:"[\\+\\.]"},hljs.XML_ATTR,hljs.XML_VALUE_QUOT,hljs.XML_VALUE_APOS]};hljs.HTML_TAGS={code:1,kbd:1,font:1,noscript:1,style:1,img:1,title:1,menu:1,tt:1,tr:1,param:1,li:1,tfoot:1,th:1,input:1,td:1,dl:1,blockquote:1,fieldset:1,big:1,dd:1,abbr:1,optgroup:1,dt:1,button:1,isindex:1,p:1,small:1,div:1,dir:1,em:1,frame:1,meta:1,sub:1,bdo:1,label:1,acronym:1,sup:1,body:1,xml:1,basefont:1,base:1,br:1,address:1,strong:1,legend:1,ol:1,script:1,caption:1,s:1,col:1,h2:1,h3:1,h1:1,h6:1,h4:1,h5:1,table:1,select:1,noframes:1,span:1,area:1,dfn:1,strike:1,cite:1,thead:1,head:1,option:1,form:1,hr:1,"var":1,link:1,b:1,colgroup:1,ul:1,applet:1,del:1,iframe:1,pre:1,frameset:1,ins:1,tbody:1,html:1,samp:1,map:1,object:1,a:1,xmlns:1,center:1,textarea:1,i:1,q:1,u:1};hljs.HTML_DOCTYPE={cN:"doctype",b:"",r:10};hljs.HTML_ATTR={cN:"attribute",b:"\\s[a-zA-Z\\:-]+=",e:"^",c:["value"]};hljs.HTML_SHORT_ATTR={cN:"attribute",b:" [a-zA-Z]+",e:"^"};hljs.HTML_VALUE={cN:"value",b:"[a-zA-Z0-9]+",e:"^"};hljs.LANGUAGES.html={dM:{c:["tag","comment","doctype","vbscript"]},cI:true,m:[hljs.XML_COMMENT,hljs.HTML_DOCTYPE,{cN:"tag",l:[hljs.IR],k:hljs.HTML_TAGS,b:"",c:["attribute"],i:"[\\+\\.]",starts:"css"},{cN:"tag",l:[hljs.IR],k:hljs.HTML_TAGS,b:"",c:["attribute"],i:"[\\+\\.]",starts:"javascript"},{cN:"tag",l:[hljs.IR],k:hljs.HTML_TAGS,b:"<[A-Za-z/]",e:">",c:["attribute"],i:"[\\+\\.]"},{cN:"css",e:"",rE:true,subLanguage:"css"},{cN:"javascript",e:"<\/script>",rE:true,subLanguage:"javascript"},hljs.HTML_ATTR,hljs.HTML_SHORT_ATTR,hljs.XML_VALUE_QUOT,hljs.XML_VALUE_APOS,hljs.HTML_VALUE,{cN:"vbscript",b:"<%",e:"%>",subLanguage:"vbscript"}]};hljs.LANGUAGES.css={dM:{c:["at_rule","id","class","attr_selector","pseudo","rules","comment"],k:hljs.HTML_TAGS,l:[hljs.IR],i:"="},cI:true,m:[{cN:"at_rule",b:"@",e:"[{;]",eE:true,l:[hljs.IR],k:{"import":1,page:1,media:1,charset:1,"font-face":1},c:["function","string","number","pseudo"]},{cN:"id",b:"\\#[A-Za-z0-9_-]+",e:"^"},{cN:"class",b:"\\.[A-Za-z0-9_-]+",e:"^",r:0},{cN:"attr_selector",b:"\\[",e:"\\]",i:"$"},{cN:"pseudo",b:":(:)?[a-zA-Z0-9\\_\\-\\+\\(\\)\\\"\\']+",e:"^"},{cN:"rules",b:"{",e:"}",c:["rule","comment"],i:"[^\\s]"},{cN:"rule",b:"[A-Z\\_\\.\\-]+\\s*:",e:";",eW:true,l:["[A-Za-z-]+"],k:{"play-during":1,"counter-reset":1,"counter-increment":1,"min-height":1,quotes:1,"border-top":1,pitch:1,font:1,pause:1,"list-style-image":1,"border-width":1,cue:1,"outline-width":1,"border-left":1,elevation:1,richness:1,"speech-rate":1,"border-bottom":1,"border-spacing":1,background:1,"list-style-type":1,"text-align":1,"page-break-inside":1,orphans:1,"page-break-before":1,"text-transform":1,"line-height":1,"padding-left":1,"font-size":1,right:1,"word-spacing":1,"padding-top":1,"outline-style":1,bottom:1,content:1,"border-right-style":1,"padding-right":1,"border-left-style":1,"voice-family":1,"background-color":1,"border-bottom-color":1,"outline-color":1,"unicode-bidi":1,"max-width":1,"font-family":1,"caption-side":1,"border-right-width":1,"pause-before":1,"border-top-style":1,color:1,"border-collapse":1,"border-bottom-width":1,"float":1,height:1,"max-height":1,"margin-right":1,"border-top-width":1,speak:1,"speak-header":1,top:1,"cue-before":1,"min-width":1,width:1,"font-variant":1,"border-top-color":1,"background-position":1,"empty-cells":1,direction:1,"border-right":1,visibility:1,padding:1,"border-style":1,"background-attachment":1,overflow:1,"border-bottom-style":1,cursor:1,margin:1,display:1,"border-left-width":1,"letter-spacing":1,"vertical-align":1,clip:1,"border-color":1,"list-style":1,"padding-bottom":1,"pause-after":1,"speak-numeral":1,"margin-left":1,widows:1,border:1,"font-style":1,"border-left-color":1,"pitch-range":1,"background-repeat":1,"table-layout":1,"margin-bottom":1,"speak-punctuation":1,"font-weight":1,"border-right-color":1,"page-break-after":1,position:1,"white-space":1,"text-indent":1,"background-image":1,volume:1,stress:1,outline:1,clear:1,"z-index":1,"text-decoration":1,"margin-top":1,azimuth:1,"cue-after":1,left:1,"list-style-position":1},c:["value"]},hljs.CBLCLM,{cN:"value",b:"^",eW:true,eE:true,c:["function","number","hexcolor","string"]},{cN:"number",b:hljs.NR,e:"^"},{cN:"hexcolor",b:"\\#[0-9A-F]+",e:"^"},{cN:"function",b:hljs.IR+"\\(",e:"\\)",c:["params"]},{cN:"params",b:"^",eW:true,eE:true,c:["number","string"]},hljs.ASM,hljs.QSM]};hljs.LANGUAGES.ini={cI:true,dM:{c:["comment","title","setting"],i:"[^\\s]"},m:[{cN:"comment",b:";",e:"$"},{cN:"title",b:"\\[",e:"\\]"},{cN:"setting",b:"^[a-z0-9_\\[\\]]+[ \\t]*=[ \\t]*",e:"$",c:["value"]},{cN:"value",b:"^",eW:true,c:["string","number"],l:[hljs.IR],k:{on:1,off:1,"true":1,"false":1,yes:1,no:1}},hljs.QSM,hljs.BE,{cN:"number",b:"\\d+",e:"^"}]};hljs.LANGUAGES.javascript={dM:{l:[hljs.UIR],c:["string","comment","number","regexp_container","function"],k:{keyword:{"in":1,"if":1,"for":1,"while":1,"finally":1,"var":1,"new":1,"function":1,"do":1,"return":1,"void":1,"else":1,"break":1,"catch":1,"instanceof":1,"with":1,"throw":1,"case":1,"default":1,"try":1,"this":1,"switch":1,"continue":1,"typeof":1,"delete":1},literal:{"true":1,"false":1,"null":1}}},m:[hljs.CLCM,hljs.CBLCLM,hljs.CNM,hljs.ASM,hljs.QSM,hljs.BE,{cN:"regexp_container",b:"("+hljs.RSR+"|case|return|throw)\\s*",e:"^",nM:true,l:[hljs.IR],k:{"return":1,"throw":1,"case":1},c:["comment","regexp"],r:0},{cN:"regexp",b:"/.*?[^\\\\/]/[gim]*",e:"^"},{cN:"function",b:"\\bfunction\\b",e:"{",l:[hljs.UIR],k:{"function":1},c:["title","params"]},{cN:"title",b:"[A-Za-z$_][0-9A-Za-z$_]*",e:"^"},{cN:"params",b:"\\(",e:"\\)",c:["string","comment"]}]};hljs.LANGUAGES.ruby=function(){var a="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?";var b=["comment","string","char","class","function","module_name","symbol","number","variable","regexp_container"];var c={keyword:{and:1,"false":1,then:1,defined:1,module:1,"in":1,"return":1,redo:1,"if":1,BEGIN:1,retry:1,end:1,"for":1,"true":1,self:1,when:1,next:1,until:1,"do":1,begin:1,unless:1,END:1,rescue:1,nil:1,"else":1,"break":1,undef:1,not:1,"super":1,"class":1,"case":1,require:1,yield:1,alias:1,"while":1,ensure:1,elsif:1,or:1,def:1},keymethods:{__id__:1,__send__:1,abort:1,abs:1,"all?":1,allocate:1,ancestors:1,"any?":1,arity:1,assoc:1,at:1,at_exit:1,autoload:1,"autoload?":1,"between?":1,binding:1,binmode:1,"block_given?":1,call:1,callcc:1,caller:1,capitalize:1,"capitalize!":1,casecmp:1,"catch":1,ceil:1,center:1,chomp:1,"chomp!":1,chop:1,"chop!":1,chr:1,"class":1,class_eval:1,"class_variable_defined?":1,class_variables:1,clear:1,clone:1,close:1,close_read:1,close_write:1,"closed?":1,coerce:1,collect:1,"collect!":1,compact:1,"compact!":1,concat:1,"const_defined?":1,const_get:1,const_missing:1,const_set:1,constants:1,count:1,crypt:1,"default":1,default_proc:1,"delete":1,"delete!":1,delete_at:1,delete_if:1,detect:1,display:1,div:1,divmod:1,downcase:1,"downcase!":1,downto:1,dump:1,dup:1,each:1,each_byte:1,each_index:1,each_key:1,each_line:1,each_pair:1,each_value:1,each_with_index:1,"empty?":1,entries:1,eof:1,"eof?":1,"eql?":1,"equal?":1,"eval":1,exec:1,exit:1,"exit!":1,extend:1,fail:1,fcntl:1,fetch:1,fileno:1,fill:1,find:1,find_all:1,first:1,flatten:1,"flatten!":1,floor:1,flush:1,for_fd:1,foreach:1,fork:1,format:1,freeze:1,"frozen?":1,fsync:1,getc:1,gets:1,global_variables:1,grep:1,gsub:1,"gsub!":1,"has_key?":1,"has_value?":1,hash:1,hex:1,id:1,"include?":1,included_modules:1,index:1,indexes:1,indices:1,induced_from:1,inject:1,insert:1,inspect:1,instance_eval:1,instance_method:1,instance_methods:1,"instance_of?":1,"instance_variable_defined?":1,instance_variable_get:1,instance_variable_set:1,instance_variables:1,"integer?":1,intern:1,invert:1,ioctl:1,"is_a?":1,isatty:1,"iterator?":1,join:1,"key?":1,keys:1,"kind_of?":1,lambda:1,last:1,length:1,lineno:1,ljust:1,load:1,local_variables:1,loop:1,lstrip:1,"lstrip!":1,map:1,"map!":1,match:1,max:1,"member?":1,merge:1,"merge!":1,method:1,"method_defined?":1,method_missing:1,methods:1,min:1,module_eval:1,modulo:1,name:1,nesting:1,"new":1,next:1,"next!":1,"nil?":1,nitems:1,"nonzero?":1,object_id:1,oct:1,open:1,pack:1,partition:1,pid:1,pipe:1,pop:1,popen:1,pos:1,prec:1,prec_f:1,prec_i:1,print:1,printf:1,private_class_method:1,private_instance_methods:1,"private_method_defined?":1,private_methods:1,proc:1,protected_instance_methods:1,"protected_method_defined?":1,protected_methods:1,public_class_method:1,public_instance_methods:1,"public_method_defined?":1,public_methods:1,push:1,putc:1,puts:1,quo:1,raise:1,rand:1,rassoc:1,read:1,read_nonblock:1,readchar:1,readline:1,readlines:1,readpartial:1,rehash:1,reject:1,"reject!":1,remainder:1,reopen:1,replace:1,require:1,"respond_to?":1,reverse:1,"reverse!":1,reverse_each:1,rewind:1,rindex:1,rjust:1,round:1,rstrip:1,"rstrip!":1,scan:1,seek:1,select:1,send:1,set_trace_func:1,shift:1,singleton_method_added:1,singleton_methods:1,size:1,sleep:1,slice:1,"slice!":1,sort:1,"sort!":1,sort_by:1,split:1,sprintf:1,squeeze:1,"squeeze!":1,srand:1,stat:1,step:1,store:1,strip:1,"strip!":1,sub:1,"sub!":1,succ:1,"succ!":1,sum:1,superclass:1,swapcase:1,"swapcase!":1,sync:1,syscall:1,sysopen:1,sysread:1,sysseek:1,system:1,syswrite:1,taint:1,"tainted?":1,tell:1,test:1,"throw":1,times:1,to_a:1,to_ary:1,to_f:1,to_hash:1,to_i:1,to_int:1,to_io:1,to_proc:1,to_s:1,to_str:1,to_sym:1,tr:1,"tr!":1,tr_s:1,"tr_s!":1,trace_var:1,transpose:1,trap:1,truncate:1,"tty?":1,type:1,ungetc:1,uniq:1,"uniq!":1,unpack:1,unshift:1,untaint:1,untrace_var:1,upcase:1,"upcase!":1,update:1,upto:1,"value?":1,values:1,values_at:1,warn:1,write:1,write_nonblock:1,"zero?":1,zip:1}};return{dM:{l:[a],c:b,k:c},m:[hljs.HCM,{cN:"comment",b:"^\\=begin",e:"^\\=end",r:10},{cN:"comment",b:"^__END__",e:"\\n$"},{cN:"params",b:"\\(",e:"\\)",l:[a],k:c,c:b},{cN:"function",b:"\\bdef\\b",e:"$|;",l:[a],k:c,c:["title","params","comment"]},{cN:"class",b:"\\b(class|module)\\b",e:"$",l:[hljs.UIR],k:c,c:["title","inheritance","comment"],k:{"class":1,module:1}},{cN:"title",b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?",e:"^",r:0},{cN:"inheritance",b:"<\\s*",e:"^",c:["parent"]},{cN:"parent",b:"("+hljs.IR+"::)?"+hljs.IR,e:"^"},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",e:"^",r:0},{cN:"number",b:"\\?\\w",e:"^"},{cN:"string",b:"'",e:"'",c:["escape","subst"],r:0},{cN:"string",b:'"',e:'"',c:["escape","subst"],r:0},{cN:"string",b:"%[qw]?\\(",e:"\\)",c:["escape","subst"],r:10},{cN:"string",b:"%[qw]?\\[",e:"\\]",c:["escape","subst"],r:10},{cN:"string",b:"%[qw]?{",e:"}",c:["escape","subst"],r:10},{cN:"string",b:"%[qw]?<",e:">",c:["escape","subst"],r:10},{cN:"string",b:"%[qw]?/",e:"/",c:["escape","subst"],r:10},{cN:"string",b:"%[qw]?%",e:"%",c:["escape","subst"],r:10},{cN:"string",b:"%[qw]?-",e:"-",c:["escape","subst"],r:10},{cN:"string",b:"%[qw]?\\|",e:"\\|",c:["escape","subst"],r:10},{cN:"module_name",b:":{2}"+a,e:"^",nM:true},{cN:"symbol",b:":"+a,e:"^"},{cN:"symbol",b:":",e:"^",c:["string"]},hljs.BE,{cN:"subst",b:"#\\{",e:"}",l:[a],k:c,c:b},{cN:"regexp_container",b:"("+hljs.RSR+")\\s*",e:"^",nM:true,c:["comment","regexp"],r:0},{cN:"regexp",b:"/",e:"/[a-z]*",i:"\\n",c:["escape"]},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))",e:"^"}]}}();hljs.LANGUAGES.sql={cI:true,dM:{l:[hljs.IR],c:["string","number","comment"],k:{keyword:{all:1,partial:1,global:1,month:1,current_timestamp:1,using:1,go:1,revoke:1,smallint:1,indicator:1,"end-exec":1,disconnect:1,zone:1,"with":1,character:1,assertion:1,to:1,add:1,current_user:1,usage:1,input:1,local:1,alter:1,match:1,collate:1,real:1,then:1,rollback:1,get:1,read:1,timestamp:1,session_user:1,not:1,integer:1,bit:1,unique:1,day:1,minute:1,desc:1,insert:1,execute:1,like:1,ilike:2,level:1,decimal:1,drop:1,"continue":1,isolation:1,found:1,where:1,constraints:1,domain:1,right:1,national:1,some:1,module:1,transaction:1,relative:1,second:1,connect:1,escape:1,close:1,system_user:1,"for":1,deferred:1,section:1,cast:1,current:1,sqlstate:1,allocate:1,intersect:1,deallocate:1,numeric:1,"public":1,preserve:1,full:1,"goto":1,initially:1,asc:1,no:1,key:1,output:1,collation:1,group:1,by:1,union:1,session:1,both:1,last:1,language:1,constraint:1,column:1,of:1,space:1,foreign:1,deferrable:1,prior:1,connection:1,unknown:1,action:1,commit:1,view:1,or:1,first:1,into:1,"float":1,year:1,primary:1,cascaded:1,except:1,restrict:1,set:1,references:1,names:1,table:1,outer:1,open:1,select:1,size:1,are:1,rows:1,from:1,prepare:1,distinct:1,leading:1,create:1,only:1,next:1,inner:1,authorization:1,schema:1,corresponding:1,option:1,declare:1,precision:1,immediate:1,"else":1,timezone_minute:1,external:1,varying:1,translation:1,"true":1,"case":1,exception:1,join:1,hour:1,"default":1,"double":1,scroll:1,value:1,cursor:1,descriptor:1,values:1,dec:1,fetch:1,procedure:1,"delete":1,and:1,"false":1,"int":1,is:1,describe:1,"char":1,as:1,at:1,"in":1,varchar:1,"null":1,trailing:1,any:1,absolute:1,current_time:1,end:1,grant:1,privileges:1,when:1,cross:1,check:1,write:1,current_date:1,pad:1,begin:1,temporary:1,exec:1,time:1,update:1,catalog:1,user:1,sql:1,date:1,on:1,identity:1,timezone_hour:1,natural:1,whenever:1,interval:1,work:1,order:1,cascade:1,diagnostics:1,nchar:1,having:1,left:1},aggregate:{count:1,sum:1,min:1,max:1,avg:1}}},m:[hljs.CNM,hljs.CBLCLM,{cN:"comment",b:"--",e:"$"},{cN:"string",b:"'",e:"'",c:["escape","squote"],r:0},{cN:"squote",b:"''",e:"^",nM:true},{cN:"string",b:'"',e:'"',c:["escape","dquote"],r:0},{cN:"dquote",b:'""',e:"^",nM:true},{cN:"string",b:"`",e:"`",c:["escape"]},hljs.BE]};hljs.LANGUAGES.java={dM:{l:[hljs.UIR],c:["javadoc","comment","string","class","number","annotation"],k:{"false":1,"synchronized":1,"int":1,"abstract":1,"float":1,"private":1,"char":1,"interface":1,"boolean":1,"static":1,"null":1,"if":1,"const":1,"for":1,"true":1,"while":1,"long":1,"throw":1,strictfp:1,"finally":1,"protected":1,"extends":1,"import":1,"native":1,"final":1,"implements":1,"return":1,"void":1,"enum":1,"else":1,"break":1,"transient":1,"new":1,"catch":1,"instanceof":1,"byte":1,"super":1,"class":1,"volatile":1,"case":1,assert:1,"short":1,"package":1,"default":1,"double":1,"public":1,"try":1,"this":1,"switch":1,"continue":1,"throws":1}},m:[{cN:"class",l:[hljs.UIR],b:"(class |interface )",e:"{",i:":",k:{"class":1,"interface":1},c:["inheritance","title"]},{cN:"inheritance",b:"(implements|extends)",e:"^",nM:true,l:[hljs.IR],k:{"extends":1,"implements":1},r:10},{cN:"title",b:hljs.UIR,e:"^"},{cN:"params",b:"\\(",e:"\\)",c:["string","annotation"]},hljs.CNM,hljs.ASM,hljs.QSM,hljs.BE,hljs.CLCM,{cN:"javadoc",b:"/\\*\\*",e:"\\*/",c:["javadoctag"],r:10},{cN:"javadoctag",b:"@[A-Za-z]+",e:"^"},hljs.CBLCLM,{cN:"annotation",b:"@[A-Za-z]+",e:"^"}]};hljs.LANGUAGES.bash=function(){var a={"true":1,"false":1};return{dM:{l:[hljs.IR],c:["string","shebang","comment","number","test_condition","string","variable"],k:{keyword:{"if":1,then:1,"else":1,fi:1,"for":1,"break":1,"continue":1,"while":1,"in":1,"do":1,done:1,echo:1,exit:1,"return":1,set:1,declare:1},literal:a}},cI:false,m:[{cN:"shebang",b:"(#!\\/bin\\/bash)|(#!\\/bin\\/sh)",e:"^",r:10},hljs.HCM,{cN:"test_condition",b:"\\[ ",e:" \\]",c:["string","variable","number"],l:[hljs.IR],k:{literal:a},r:0},{cN:"test_condition",b:"\\[\\[ ",e:" \\]\\]",c:["string","variable","number"],l:[hljs.IR],k:{literal:a}},{cN:"variable",b:"\\$([a-zA-Z0-9_]+)\\b",e:"^"},{cN:"variable",b:"\\$\\{(([^}])|(\\\\}))+\\}",e:"^",c:["number"]},{cN:"string",b:'"',e:'"',i:"\\n",c:["escape","variable"],r:0},{cN:"string",b:'"',e:'"',i:"\\n",c:["escape","variable"],r:0},hljs.BE,hljs.CNM,{cN:"comment",b:"\\/\\/",e:"$",i:"."}]}}();rubyworks-ansi-291cecc/docs/assets/scripts/jquery.js000066400000000000000000001576461516262404200230270ustar00rootroot00000000000000/* * jQuery JavaScript Library v1.3.2 * http://jquery.com/ * * Copyright (c) 2009 John Resig * Dual licensed under the MIT and GPL licenses. * http://docs.jquery.com/License * * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009) * Revision: 6246 */ (function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("",""]||!O.indexOf("",""]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
"]||!O.indexOf("",""]||(!O.indexOf("",""]||!O.indexOf("",""]||!o.support.htmlSerialize&&[1,"div
","
"]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}}); /* * Sizzle CSS Selector Engine - v0.9.3 * Copyright 2009, The Dojo Foundation * Released under the MIT, BSD, and GPL Licenses. * More information: http://sizzlejs.com/ */ (function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return UT[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="

";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="
";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("
").append(M.responseText.replace(//g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend({get:function(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.extend(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.data=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)){var H=document.getElementsByTagName("head")[0];var T=document.createElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();T.onload=T.onreadystatechange=null;H.removeChild(T)}}}H.appendChild(T);return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}return J},handleError:function(F,H,E,G){if(F.error){F.error(H,E,G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunction(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.concat.apply([],d.slice(0,E)),function(){G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}o.data(this[H],"olddisplay",K)}}for(var H=0,F=this.length;H=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};return E},easing:{linear:function(G,H,E,F){return E+F*G},swing:function(G,H,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)&&!n){n=setInterval(function(){var K=o.timers;for(var J=0;J=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.elem)}return false}else{var J=G-this.startTime;this.state=J/this.options.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"opacity",E.now)},_default:function(E){if(E.elem.style&&E.elem.style[E.prop]!=null){E.elem.style[E.prop]=E.now+E.unit}else{E.elem[E.prop]=E.now}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{top:N,left:I}}}o.offset={initialize:function(){if(this.initialized){return}var L=document.body,F=document.createElement("div"),H,G,N,I,M,E,J=L.style.marginTop,K='
';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:function(E){o.offset.initialized||o.offset.initialize();var G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||this[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxModel&&document.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(I,G){var E=I?"Left":"Top",H=I?"Right":"Bottom",F=G.toLowerCase();o.fn["inner"+G]=function(){return this[0]?o.css(this[0],F,false,"padding"):null};o.fn["outer"+G]=function(K){return this[0]?o.css(this[0],F,false,K?"margin":"border"):null};var J=G.toLowerCase();o.fn[J]=function(K){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+G]||document.body["client"+G]:this[0]==document?Math.max(document.documentElement["client"+G],document.body["scroll"+G],document.documentElement["scroll"+G],document.body["offset"+G],document.documentElement["offset"+G]):K===g?(this.length?o.css(this[0],J):null):this.css(J,typeof K==="string"?K:K+"px")}})})();rubyworks-ansi-291cecc/docs/assets/scripts/jquery.tabs.js000066400000000000000000000070101516262404200237320ustar00rootroot00000000000000eval(function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('(5($){$.1G.g=5(9,2){4(P 9==\'2a\')2=9;2=$.1d({9:(9&&P 9==\'2r\'&&9>0)?--9:0,1c:j,19:j,1g:j,1e:j,Q:\'2d\',1z:j,1D:j,1K:1J,n:j,u:\'g-2e\',10:\'g-R\',N:\'1k\'},2||{});$.c.1l=$.c.C&&P 2f==\'5\';3 1h=5(){1A(0,0)};A 6.D(5(){3 l=6;4(r.7){$(\'>Z:q(0)>T>a\',6).D(5(i){4(6.7==r.7){2.9=i;4($.c.C){3 8=$(r.7);3 I=r.7.J(\'#\',\'\');8.t(\'\');O(5(){8.t(I)},2g)}1h();4($.c.2h)O(1h,2i);A 1J}})}3 g=$(\'>Z:q(0)>T>a\',6);$(\'>\'+2.N,6).2k(\':q(\'+2.9+\')\').U(2.10);$(\'>Z:q(0)>T:q(\'+2.9+\')\',6).U(2.u);4(2.1K){3 S=$(\'>\'+2.N,l);3 14=5(1L){3 18=$.2l(S.F(),5(v){3 h,1j=$(v);4(1L){4($.c.1l){v.y.2n(\'1M\');v.y.d=\'\';v.11=j}h=1j.B({\'1m-d\':\'\'}).d()}f{h=1j.d()}A h}).2o(5(a,b){A b-a});4($.c.1l){S.D(5(){6.11=18[0]+\'1B\';6.y.2p(\'1M\',\'6.y.d = 6.11 ? 6.11 : "1P"\')})}f{S.B({\'1m-d\':18[0]+\'1B\'})}};14();3 H=l.1r;3 1i=l.G;3 12=$(\'#g-1o-1O-16\').F(0)||$(\'<1u t="g-1o-1O-16">M\').B({1N:\'1Q\',1Z:\'1R\',1T:\'1s\'}).1U(m.17).F(0);3 V=12.G;1W(5(){3 L=l.1r;3 15=l.G;3 Y=12.G;4(15>1i||L!=H||Y!=V){14((L>H||Y0){4($.c.C){3 I=6.7.J(\'#\',\'\');8.t(\'\');O(5(){8.t(I)},0)}3 1H=6;3 z=$(\'>\'+2.N+\':23\',l);3 n;4(P 2.n==\'5\')n=5(){2.n.24(8[0],[8[0],z[0]])};3 p={},o={};3 w,s;4(2.19||2.1c){4(2.19){p[\'d\']=\'1b\';o[\'d\']=\'R\'}4(2.1c){p[\'E\']=\'1b\';o[\'E\']=\'R\'}w=s=2.Q}f{4(2.1g){p=$.1d(p,2.1g);w=2.1z||2.Q}f{p[\'E\']=\'1b\';w=1f}4(2.1e){o=$.1d(o,2.1e);s=2.1D||2.Q}f{o[\'E\']=\'R\';s=1f}}z.1w(o,s,5(){$(1H.1I).U(2.u).2b().1n(2.u);8.1n(2.10).1w(p,w,5(){4($.c.C){z[0].y.2m=\'\';z.U(2.10).B({1N:\'\',1p:\'\',d:\'\'})}8.B({d:\'\',1p:\'\'});4(n)n()})})}f{1S(\'1V 13 1X 1Y l.\')}}3 1C=1a.20||m.K&&m.K.1t||m.17.1t||0;3 1E=1a.22||m.K&&m.K.1x||m.17.1x||0;O(5(){1a.1A(1C,1E)},0);6.27()})})};$.1G.29=5(X){A 6.D(5(){3 i=X&&X>0&&X-1||0;3 x=$(\'>Z:q(0)>T>a\',6).q(i);3 7=x[0].7;4($(7).13(\':1s\')){4($.c.C){x.W();4($.k){$.k.1F(7)}r.7=7.J(\'#\',\'\')}f 4($.c.25){3 1v=$(\'<1q 26="\'+7+\'"><1k><28 2c="1y" 2j="h" />\').F(0);1v.1y();x.W();4($.k){$.k.1F(7)}}f{r.7=7.J(\'#\',\'\');4(!$.k){x.W()}}}})}})(2q);',62,152,'||settings|var|if|function|this|hash|toShow|initial|||browser|height||else|tabs|||null|history|container|document|callback|hideAnim|showAnim|eq|location|hideSpeed|id|selectedClass|el|showSpeed|tabToTrigger|style|toHide|return|css|msie|each|opacity|get|offsetHeight|cachedWidth|toShowId|replace|documentElement|currentWidth||tabStruct|setTimeout|typeof|fxSpeed|hide|tabsContents|li|addClass|cachedFontSize|click|tabIndex|currentFontSize|ul|hideClass|minHeight|watchFontSize|is|_setAutoHeight|currentHeight|size|body|heights|fxSlide|window|show|fxFade|extend|fxHide|50|fxShow|_unFocus|cachedHeight|jq|div|msie6|min|removeClass|watch|overflow|form|offsetWidth|hidden|scrollLeft|span|tempForm|animate|scrollTop|submit|fxShowSpeed|scrollTo|px|scrollX|fxHideSpeed|scrollY|setHash|fn|clicked|parentNode|false|fxAutoHeight|reset|behaviour|display|font|1px|block|absolute|alert|visibility|appendTo|There|setInterval|no|such|position|pageXOffset|observe|pageYOffset|visible|apply|safari|action|blur|input|triggerTab|object|siblings|type|normal|selected|XMLHttpRequest|500|opera|100|value|not|map|filter|removeExpression|sort|setExpression|jQuery|number'.split('|'),0,{})) rubyworks-ansi-291cecc/docs/assets/styles/000077500000000000000000000000001516262404200207635ustar00rootroot00000000000000rubyworks-ansi-291cecc/docs/assets/styles/highlight.css000066400000000000000000000031541516262404200234470ustar00rootroot00000000000000/* github.com style (c) Vasily Polovnyov */ /* NOTE: This has been included in the rdoc.css stylesheet rather then have it's own file simply b/c I have not figured out how to utilize my own generator to be able to copy additional files. */ pre code { display: block; color: #eee; background: #f8f8ff; background: #333; -moz-border-radius: 10px; border-radius: 10px; } code .comment, .template_comment, .diff .header, .javadoc { color: #998; font-style: italic } code .keyword, .css .rule .keyword, .winutils, .javascript .title, .lisp .title, .subst { color: #77f; font-weight: bold } code .number, .hexcolor { color: #40a070 } code .string, .attribute .value, .phpdoc { color: #d14 } code .title, .id { color: #900; font-weight: bold } code .javascript .title, .lisp .title, .subst { font-weight: normal } code .class .title { color: #458; font-weight: bold } code .tag, .css .keyword, .html .keyword, .tag .title, .django .tag .keyword { color: #000080; font-weight: normal } code .attribute, .variable, .instancevar, .lisp .body { color: #008080 } code .regexp { color: #009926 } code .class { color: #458; font-weight: bold } code .symbol, .lisp .keyword { color: #990073 } code .builtin, .built_in, .lisp .title { color: #0086b3 } code .preprocessor, .pi, .doctype, .shebang, .cdata { color: #999; font-weight: bold } code .deletion { background: #fdd } code .addition { background: #dfd } code .diff .change { background: #0086b3 } code .chunk { color: #aaa } rubyworks-ansi-291cecc/docs/assets/styles/id.css000066400000000000000000000045721516262404200221010ustar00rootroot00000000000000/* ID STYLES */ /* #header */ #header { border-bottom: 0px solid #ccc; padding: 20px; text-align: center; background: url(../images/color_bars.gif) #ffffff; } #header .title { padding: 0; font-size: 40px; vertical-align: absmiddle; } #header .title h1 { font-size: 190px; font-weight: bold; margin: 10px 0 0 0; font-family: monospace; } #header .title h1 { color: #ffffff; text-shadow: 1px 1px 5px #333; } #header .title pre { background: transparent; } #header .title h2 { color: red; font-weight: bold; margin: 0; text-shadow: 1px 1px 5px #333; } /* #nav */ #nav { text-align: center; margin: 20px auto; } #nav img { height: 128px; width: 128px; } #nav td { text-align: center; padding: 40px; } #nav a { font-weight: bold; font-size: 20px; } /* NOT USED */ #nav ul { list-style-type: none; margin: 0px; padding: 0px; width: 100%; position: relative; } #nav ul li { margin: 0 1px 10px 0; line-height: 20px; white-space:nowrap; } #nav ul li a { border-top: 0 solid; } #nav ul li a { font-weight: bold; text-decoration: none; font-size: 30px; } #nav ul li a:hover { text-decoration: underline; } #nav ul li a:active { text-decoration: underline; } #nav ul { background: transparent; } #nav ul li a { color: #00415A; border-color: #80C1DA; } /* #main */ .main { padding: 10px 0 30px 0; } .main { } .main a { font-size: 100%; } .main a:hover { text-decoration: underline; } .main h2 { font-size: 2em; font-weight: bold; } .main h3 { font-style: italic; } /* #doc */ #doc { font-family: helvetica, sans-serif; line-height: 150%; background-color: #222; color: white; padding: 3em 2em 2em 2em; } #doc a { color: #ff415A; } #doc a:hover { } #doc p { font-weight: bold; font-size: 130%; } #doc h2 { color: #ff0000; border-color: #80C1DA; margin-top: 0; padding-top: 0; } #doc h3 { border-color: #80C1DA; } #readme { margin-top: 0; padding-top: 20px; border-top: 0px solid #ccc; } #readme ol, ul { list-style: square; margin-left: 24px; } /* #footer */ #footer { margin-top: 0; padding-top: 30px; border-top: 0px solid #ccc; text-align: center; } #footer .advert { border: 1px solid :eee; } #footer .copyright { margin-top: 20px; padding: 20px 0px 35px 0px; font-size: 0.8em; color: #888; } /* CLASS STYLES */ .centered { width: 90%; margin: 10px auto; background: #ffffff; padding: 5px 40px; } .colorized { background: #0082B4; color: #333333; } .highlighted { background: #0082B4; color: #80C1DA; } rubyworks-ansi-291cecc/docs/assets/styles/reset.css000066400000000000000000000020321516262404200226140ustar00rootroot00000000000000/* http://meyerweb.com/eric/tools/css/reset/ */ /* v1.0 | 20080212 */ html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td { margin: 0; padding: 0; border: 0; outline: 0; font-size: 100%; vertical-align: baseline; background: transparent; } body { line-height: 1; } ol, ul { list-style: none; } li p { margin: 0; padding: 0; } blockquote, q { quotes: none; } blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; } /* remember to define focus styles! */ :focus { outline: 0; } /* remember to highlight inserts somehow! */ ins { text-decoration: none; } del { text-decoration: line-through; } /* tables still need 'cellspacing="0"' in the markup */ table { border-collapse: collapse; border-spacing: 0; } rubyworks-ansi-291cecc/docs/assets/styles/tag.css000066400000000000000000000014061516262404200222510ustar00rootroot00000000000000/* TAG STYLES */ html { font-family: helvetica, sans-serif; font-size: 100%; } body { position: relative; color: #222233; } li { padding: 3px 0; font-size: 80%; line-height: 150%; } pre { margin: 10px 0; padding: 10px 10px 0px 10px; font-family: monospace; color: white; background-color: #333; } pre.ruby { padding: 10px; } pre code { padding: 10px 10px; } img { border: none; } td { vertical-align: top; text-align: left; } p { text-align: justify; font-size: 100%; line-height: 150%; margin: 0 0 1.2em 0; } a { text-decoration: none; color: #00415A; } a:hover { text-decoration: underline; } /* headers */ h1, h2, h3, h4, h5, h6 { margin: 1.5em 0 1em 0; } h1 { font-size: 200%; } h2 { font-size: 150%; } h3 { font-size: 120%; } h4 { font-size: 100%; } rubyworks-ansi-291cecc/docs/index.html000066400000000000000000000143161516262404200201400ustar00rootroot00000000000000 ANSI for RUBY

The Ruby ANSI project is a brilliant collection of ANSI escape code related libraries enabling ANSI code based colorization and stylization of console output in a variety of formats and layouts.

Included in the library are the Code module, which is the heart of the system, a Mixin module for including color methods into your own classes, a Logger, a ProgressBar, a String subclass and more. The library also includes a Terminal module which provides information about the current output device.


rubyworks-ansi-291cecc/docs/readme.html000066400000000000000000000072771516262404200202760ustar00rootroot00000000000000

ANSI

Home / API / Code / Mail

DESCRIPTION

The ANSI project is a collection of ANSI escape code related libraries enabling ANSI code based colorization and stylization of output. It is very nice for beautifying shell output.

This collection is based on a set of scripts spun-off from Ruby Facets. Included are Code (used to be ANSICode), Logger, ProgressBar and String. In addition the library includes Terminal which provides information about the current output device.

FEATURES

  • ANSI::Code provides ANSI codes as module functions.

  • String#ansi makes common usage very easy and elegant.

  • ANSI::Mixin provides an alternative mixin (like colored gem).

  • Very Good coverage of standard ANSI codes.

  • Additional clases for colorized columns, tables, loggers and more.

RELEASE NOTES

Please see HISTORY file.

SYNOPSIS

There are a number of modules and classes provided by the ANSI package. To get a good understanding of them it is best to pursue the QED documents or the API documentation.

At the heart of all the provided libraries lies the ANSI::Code module which defines ANSI codes as constants and methods. For example:

require 'ansi/code'

ANSI.red + "Hello" + ANSI.blue + "World"
=> "\e[31mHello\e[34mWorld"

Or in block form.

ANSI.red{ "Hello" } + ANSI.blue{ "World" }
=> "\e[31mHello\e[0m\e[34mWorld\e[0m"

The methods defined by this module are used throughout the rest of the system.

INSTALLATION

To install with RubyGems simply open a console and type:

$ sudo gem install ansi

Local installation requires Setup.rb (gem install setup), then download the tarball package and type:

$ tar -xvzf ansi-1.0.0.tgz
$ cd ansi-1.0.0
$ sudo setup.rb all

Windows users use ‘ruby setup.rb all’.

LICENSE & COPYRIGHTS

Copyright © 2009 Rubyworks

This program is redistributable under the terms of the FreeBSD license.

Some pieces of the code are copyrighted by others.

See COPYING.rdoc file for details.

rubyworks-ansi-291cecc/lib/000077500000000000000000000000001516262404200157545ustar00rootroot00000000000000rubyworks-ansi-291cecc/lib/ansi.rb000066400000000000000000000006521516262404200172360ustar00rootroot00000000000000# ANSI namespace module contains all the ANSI related classes. module ANSI end require 'ansi/version' require 'ansi/core' require 'ansi/code' require 'ansi/bbcode' require 'ansi/columns' require 'ansi/diff' require 'ansi/logger' require 'ansi/mixin' require 'ansi/progressbar' require 'ansi/string' require 'ansi/table' require 'ansi/terminal' # Kernel method def ansi(string, *codes) ANSI::Code.ansi(string, *codes) end rubyworks-ansi-291cecc/lib/ansi/000077500000000000000000000000001516262404200167065ustar00rootroot00000000000000rubyworks-ansi-291cecc/lib/ansi/bbcode.rb000066400000000000000000000300721516262404200204530ustar00rootroot00000000000000# BBCode # # Copyright (c) 2002 Thomas-Ivo Heinen # # This module is free software. You may use, modify, and/or redistribute this # software under the same terms as Ruby. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. # module ANSI # TODO: Integrate BBCode with Code module. # The BBCode module helps ease the separation of core and frontend with the # core (or submodules) being still able to say, what colors shall be used # in it's responses. This is achieved by encoding formatting information # using the BBCode tokens. This enables you to "pipe" layout information # such as colors, style, font, size and alignment through the core to # the frontend. # # Additionally it converts markups/codes between ANSI, HTML and BBCode # almost freely ;) # # # Converting a bbcode string to ANSI and XHTML # str = "this is [COLOR=red]red[/COLOR], this is [B]bold[/B]" # print( BBCode.bbcode_to_ansi(str) ) # print( BBCode.bbcode_to_html(str) ) # module BBCode ## ANSIname => ANSIcode LUT ANSINAME2CODE= { "reset" => "\e[0m", "bold" => "\e[1m", "underline" => "\e[4m", "blink" => "\e[5m", "reverse" => "\e[7m", "invisible" => "\e[8m", "black" => "\e[0;30m", "darkgrey" => "\e[1;30m", "red" => "\e[0;31m", "lightred" => "\e[1;31m", "green" => "\e[0;32m", "lightgreen" => "\e[1;32m", "brown" => "\e[0;33m", "yellow" => "\e[1;33m", "blue" => "\e[0;34m", "lightblue" => "\e[1;34m", "purple" => "\e[0;35m", "magenta" => "\e[1;35m", "cyan" => "\e[1;36m", "lightcyan" => "\e[1;36m", "grey" => "\e[0;37m", "white" => "\e[1;37m", "bgblack" => "\e[40m", "bgred" => "\e[41m", "bggreen" => "\e[42m", "bgyellow" => "\e[43m", "bgblue" => "\e[44m", "bgmagenta" => "\e[45m", "bgcyan" => "\e[46m", "bgwhite" => "\e[47m" } ## BBColor => ANSIname LUT BBCOLOR2ANSI = { "skyblue" => "blue", "royalblue" => "blue", "blue" => "blue", "darkblue" => "blue", "orange" => "red", "orangered" => "red", "crimson" => "red", "red" => "lightred", "firebrick" => "red", "darkred" => "red", "green" => "green", "limegreen" => "green", "seagreen" => "green", "darkgreen" => "green", "deeppink" => "magenta", "tomato" => "red", "coral" => "cyan", "purple" => "purple", "indigo" => "blue", "burlywood" => "red", "sandybrown"=> "red", "sierra" => "sierra", "chocolate" => "brown", "teal" => "teal", "silver" => "white", "black" => "black", "yellow" => "yellow", "magenta" => "magenta", "cyan" => "cyan", "white" => "white" } ## ANSInames => BBCode LUT ANSINAME2BBCODE = { "bold" => "B", "underline" => "U", "reverse" => "I", "red" => "COLOR=red", "blue" => "COLOR=blue", "green" => "COLOR=green", "cyan" => "COLOR=cyan", "magenta"=> "COLOR=deeppink", "purple" => "COLOR=purple", "black" => "COLOR=black", "white" => "COLOR=white", "yellow" => "COLOR=yellow", "brown" => "COLOR=chocolate" } ## Needed for alignments @@width = 80 # --------------------------- # Returns the ANSI sequence for given color, if existant def BBCode.ansi(colorname) colorname.strip! return ANSINAME2CODE[ colorname.downcase ] end # --- strip_bbcode( string ) # Will strip any BBCode tags from the given string. def BBCode.strip_bbcode(string) string.strip! return string.gsub(/\[[A-Za-z0-9\/=]+\]/, "") end # Returns the string with all ansi escape sequences converted to BBCodes def BBCode.ansi_to_bbcode(string) return "" if string.nil? || string.to_s.strip.empty? result = "" tagstack = [] ## Iterate over input lines string.split("\n").each do |line| ## Iterate over found ansi sequences line.scan(/\e\[[0-9;]+m/).each do |seq| ansiname = ANSINAME2CODE.invert["#{seq}"] ## Pop last tag and form closing tag if ansiname == "reset" lasttag = tagstack.pop bbname = "/" + String.new( lasttag.split("=")[0] ) ## Get corresponding BBCode tag + Push to stack else bbname = ANSINAME2BBCODE[ansiname] tagstack.push(bbname) end ## Replace ansi sequence by BBCode tag replace = sprintf("[%s]", bbname) line.sub!(seq, replace) end ## Append converted line result << sprintf("%s\n", line) end ## Some tags are unclosed while !tagstack.empty? result << sprintf("[/%s]", String.new(tagstack.pop.split("=")[0]) ) end return result end # Converts a BBCode string to one with ANSI sequences. # Returns the string with all formatting instructions in BBCodes converted # to ANSI code sequences / aligned with spaces to specified width. def BBCode.bbcode_to_ansi(string, usecolors = true) return "" if string.nil? || string.to_s.strip.empty? result = "" return BBCode.strip_bbcode(string) if !usecolors ## Iterate over lines string.split("\n").each do |line| ## TODO: stacking? other styles! ANSINAME2BBCODE.each do |key,val| line.gsub!(/\[#{val}\]/, ANSINAME2CODE[key]) line.gsub!(/\[\/#{val}\]/, ANSINAME2CODE["reset"]) end ## Fonttypes and sizes not available line.gsub!(/\[SIZE=\d\]/, "") line.gsub!(/\[\/SIZE\]/, "") line.gsub!(/\[FONT=[^\]]*\]/, "") line.gsub!(/\[\/FONT\]/, "") ## Color-mapping colors = line.scan(/\[COLOR=(.*?)\]/i) colors = colors.collect{|s| s[0].to_s} if !colors.nil? colors.each do |col| name = BBCOLOR2ANSI[col.downcase] name = BBCOLOR2ANSI["white"] if name.nil? code = ANSINAME2CODE[name] line.gsub!(/\[COLOR=#{col}\]/i, code) end line.gsub!(/\[\/COLOR\]/, ANSINAME2CODE["reset"]) ## TODO: Alignment ## TODO: IMGs ## TODO: EMAILs ## TODO: URLs ## TODO: QUOTEs ## TODO: LISTs result << sprintf("%s\n", line) end return result end # Converts a HTML string into one with BBCode markup (TODO) # Returns the (X)HTML markup string as BBCode def BBCode.html_to_bbcode(string) return "" if string.nil? || string.to_s.strip.empty? result = "" ## Iterate over lines string.split(/
/i).each do |line| styles = { "strong" => "b", "b" => "b", "em" => "i", "i" => "i", "u" => "u" } ## preserve B, I, U styles.each do |html,code| line.gsub!(/<#{html}>/i, "[#{code.upcase}]") line.gsub!(/<\/#{html}>/i, "[/#{code.upcase}]") end ## TODO: COLORs ## TODO: SIZEs ## TODO: FONTs ## EMAIL line.gsub!(/.*?<\/a>/i, "[EMAIL]\\1[/EMAIL]") ## URL line.gsub!(/(.*?)<\/a>/i, "[URL=\\1]\\2[/URL]") ## Other refs + closing tags => throw away line.gsub!(//i, "") line.gsub!(/<\/a>/i, "") ## IMG #line.gsub!(//i, "[IMG=\\1]") line.gsub!(//i, "[IMG]\\1[/IMG]") ## CENTER (right/left??) line.gsub!(/
/i, "[ALIGN=center]") line.gsub!(/<\/center>/i, "[/ALIGN]") ## QUOTE line.gsub!(/<(?:xmp|pre)>/i, "[QUOTE]") line.gsub!(/<\/(?:xmp|pre)>/i, "[/QUOTE]") ## LIST line.gsub!(/
    /i, "\n[LIST]\n") line.gsub!(/<\/ul>/i, "\n[/LIST]\n") line.gsub!(/
  • */i, "\n[*] ") ## Unkown tags => throw away line.gsub!(/<.*? *\/?>/, "") result << sprintf("%s
    \n", line) end return result.gsub!(/
    /i, "\n") end # Converts a BBCode string to one with HTML markup. # Returns the string with all formatting instructions in # BBCodes converted to XHTML markups. def BBCode.bbcode_to_html(string) return "" if string.nil? || string.to_s.strip.empty? result = "" quote = 0 ## Iterate over lines string.split("\n").each do |line| styles = { "b" => "strong", "i" => "em", "u" => "u" } ## preserve B, I, U styles.each do |code,html| line.gsub!(/\[#{code}\]/i, "<#{html}>") line.gsub!(/\[\/#{code}\]/i, "") end ## COLOR => font color=... (TODO: should be numeric!) line.gsub!(/\[COLOR=(.*?)\]/i, "") line.gsub!(/\[\/COLOR\]/i, "") ## SIZE => font size=... line.gsub!(/\[SIZE=(.*?)\]/i, "") line.gsub!(/\[\/SIZE\]/i, "") ## URL line.gsub!(/\[URL\]([^\[]+?)\[\/URL\]/i, "
    \\1") line.gsub!(/\[URL=(.*?)\](.+?)\[\/URL\]/i, "\\2") ## IMG line.gsub!(/\[IMG=(.*?)\]/i, "") ## ALIGN=center (TODO: right, left) line.gsub!(/\[ALIGN=center\]/i, "
    ") line.gsub!(/\[ALIGN=right\]/i, "
    ") line.gsub!(/\[ALIGN=left\]/i, "
    ") line.gsub!(/\[\/ALIGN\]/i, "
    ") ## QUOTE quote+=1 if line =~ /\[QUOTE\]/i quote-=1 if (line =~ /\[\/QUOTE\]/i) && (quote > -1) line.gsub!(/\[QUOTE\]/i, "
    \n")
                line.gsub!(/\[\/QUOTE\]/i, "
    \n") line.gsub!(/^/, ">"*quote) if quote > 0 ## EMAIL line.gsub!(/\[EMAIL\](.*?)\[\/EMAIL\]/i, "\\1") ## LIST (TODO: LIST=1, LIST=A) line.gsub!(/\[LIST(?:=(.*?))?\]/i, "\n
      \n") line.gsub!(/\[\/LIST\]/i, "\n
    \n") line.gsub!(/\[\*\]/i, "\n
  • ") ## FONT => font ?????? ## ?BLUR?, FADE? result << sprintf("%s
    \n", line) end return result end # -- Transitive methods --------------- # Converts an ANSI string to one with HTML markup. # Returns the string with ANSI code sequences converted to XHTML markup. def BBCode.ansi_to_html(string) bbcoded = BBCode.ansi_to_bbcode(string ) htmled = BBCode.bbcode_to_html(bbcoded) return htmled end # Returns the (X)HTML markup code as ANSI sequences def BBCode.html_to_ansi(string) bbcoded = BBCode.html_to_bbcode(string ) ansied = BBCode.bbcode_to_ansi(bbcoded) return ansied end end #module BBCode end rubyworks-ansi-291cecc/lib/ansi/chain.rb000066400000000000000000000012001516262404200203060ustar00rootroot00000000000000require 'ansi/code' module ANSI # ANSI::Chain was inspired by Kazuyoshi Tlacaelel's Isna library. # class Chain # def initialize(string) @string = string.to_s @codes = [] end # attr :string # attr :codes # def method_missing(s, *a, &b) if ANSI::CHART.key?(s) @codes << s self else super(s, *a, &b) end end # def to_s if codes.empty? result = @string else result = Code.ansi(@string, *codes) codes.clear end result end # def to_str to_s end end end rubyworks-ansi-291cecc/lib/ansi/chart.rb000066400000000000000000000057261516262404200203460ustar00rootroot00000000000000module ANSI # Table of codes used throughout the system. # # @see http://en.wikipedia.org/wiki/ANSI_escape_code CHART = { :clear => 0, :reset => 0, :bright => 1, :bold => 1, :faint => 2, :dark => 2, :italic => 3, :underline => 4, :underscore => 4, :blink => 5, :slow_blink => 5, :rapid => 6, :rapid_blink => 6, :invert => 7, :inverse => 7, :reverse => 7, :negative => 7, :swap => 7, :conceal => 8, :concealed => 8, :hide => 9, :strike => 9, :default_font => 10, :font_default => 10, :font0 => 10, :font1 => 11, :font2 => 12, :font3 => 13, :font4 => 14, :font5 => 15, :font6 => 16, :font7 => 17, :font8 => 18, :font9 => 19, :fraktur => 20, :bright_off => 21, :bold_off => 21, :double_underline => 21, :clean => 22, :italic_off => 23, :fraktur_off => 23, :underline_off => 24, :blink_off => 25, :inverse_off => 26, :positive => 26, :conceal_off => 27, :show => 27, :reveal => 27, :crossed_off => 29, :crossed_out_off => 29, :black => 30, :red => 31, :green => 32, :yellow => 33, :blue => 34, :magenta => 35, :cyan => 36, :white => 37, :on_black => 40, :on_red => 41, :on_green => 42, :on_yellow => 43, :on_blue => 44, :on_magenta => 45, :on_cyan => 46, :on_white => 47, :frame => 51, :encircle => 52, :overline => 53, :frame_off => 54, :encircle_off => 54, :overline_off => 55, } # SPECIAL_CHART = { :save => "\e[s", # Save current cursor positon. :restore => "\e[u", # Restore saved cursor positon. :clear_eol => "\e[K", # Clear to the end of the current line. :clr => "\e[K", # Clear to the end of the current line. :clear_right => "\e[0K", # Clear to the end of the current line. :clear_left => "\e[1K", # Clear to the start of the current line. :clear_line => "\e[2K", # Clear the entire current line. :clear_screen => "\e[2J", # Clear the screen and move cursor to home. :cls => "\e[2J", # Clear the screen and move cursor to home. :cursor_hide => "\e[?25l", # Hide the cursor. :cursor_show => "\e[?25h" # Show the cursor. } end rubyworks-ansi-291cecc/lib/ansi/code.rb000066400000000000000000000213201516262404200201430ustar00rootroot00000000000000module ANSI # Global variable can be used to prevent ANSI codes # from being used in ANSI's methods that do so to string. # # NOTE: This has no effect on methods that return ANSI codes. $ansi = true if RUBY_PLATFORM =~ /(win32|w32)/ begin require 'Win32/Console/ANSI' rescue LoadError warn "ansi: 'gem install win32console' to use color on Windows" $ansi = false end end require 'ansi/constants' # TODO: up, down, right, left, etc could have yielding methods too? # ANSI Codes # # Ansi::Code module makes it very easy to use ANSI codes. # These are especially nice for beautifying shell output. # # Ansi::Code.red + "Hello" + Ansi::Code.blue + "World" # => "\e[31mHello\e[34mWorld" # # Ansi::Code.red{ "Hello" } + Ansi::Code.blue{ "World" } # => "\e[31mHello\e[0m\e[34mWorld\e[0m" # # IMPORTANT! Do not mixin Ansi::Code, instead use {ANSI::Mixin}. # # See {ANSI::CHART} for list of all supported codes. # module Code extend self # include ANSI Constants include Constants # Regexp for matching most ANSI codes. PATTERN = /\e\[(\d+)m/ # ANSI clear code. ENDCODE = "\e[0m" # List of primary styles. def self.styles %w{bold dark italic underline underscore blink rapid reverse negative concealed strike} end # List of primary colors. def self.colors %w{black red green yellow blue magenta cyan white} end # Return ANSI code given a list of symbolic names. def [](*codes) code(*codes) end # Dynamically create color on color methods. # # @deprecated # colors.each do |color| colors.each do |on_color| module_eval <<-END, __FILE__, __LINE__ def #{color}_on_#{on_color}(string=nil) if string return string unless $ansi #warn "use ANSI block notation for future versions" return #{color.upcase} + ON_#{color.upcase} + string + ENDCODE end if block_given? return yield unless $ansi #{color.upcase} + ON_#{on_color.upcase} + yield.to_s + ENDCODE else #{color.upcase} + ON_#{on_color.upcase} end end END end end # Use method missing to dispatch ANSI code methods. def method_missing(code, *args, &blk) esc = nil if CHART.key?(code) esc = "\e[#{CHART[code]}m" elsif SPECIAL_CHART.key?(code) esc = SPECIAL_CHART[code] end if esc if string = args.first return string unless $ansi #warn "use ANSI block notation for future versions" return "#{esc}#{string}#{ENDCODE}" end if block_given? return yield unless $ansi return "#{esc}#{yield}#{ENDCODE}" end esc else super(code, *args, &blk) end end # TODO: How to deal with position codes when $ansi is false? # Should we raise an error or just not push the codes? # For now, we will leave this it as is. # Like +move+ but returns to original position after # yielding the block. def display(line, column=0) #:yield: result = "\e[s" result << "\e[#{line.to_i};#{column.to_i}H" if block_given? result << yield result << "\e[u" #elsif string # result << string # result << "\e[u" end result end # Move cursor to line and column. def move(line, column=0) "\e[#{line.to_i};#{column.to_i}H" end # Move cursor up a specified number of spaces. def up(spaces=1) "\e[#{spaces.to_i}A" end # Move cursor down a specified number of spaces. def down(spaces=1) "\e[#{spaces.to_i}B" end # Move cursor left a specified number of spaces. def left(spaces=1) "\e[#{spaces.to_i}D" end alias :back :left # Move cursor right a specified number of spaces. def right(spaces=1) "\e[#{spaces.to_i}C" end alias :forward :right ## #def position # "\e[#;#R" #end # Apply ANSI codes to a first argument or block value. # # @example # ansi("Valentine", :red, :on_white) # # @example # ansi(:red, :on_white){ "Valentine" } # # @return [String] # String wrapped ANSI code. # def ansi(*codes) #:yield: if block_given? string = yield.to_s else # first argument must be the string string = codes.shift.to_s end return string unless $ansi c = code(*codes) c + string.gsub(ENDCODE, ENDCODE + c) + ENDCODE end # TODO: Allow selective removal using *codes argument? # Remove ANSI codes from string or block value. # # @param [String] string # String from which to remove ANSI codes. # # @return [String] # String wrapped ANSI code. # def unansi(string=nil) #:yield: if block_given? string = yield.to_s else string = string.to_s end string.gsub(PATTERN, '') end # Alias for #ansi method. # # @deprecated # Here for backward compatibility. alias_method :style, :ansi # Alias for #unansi method. # # @deprecated # Here for backwards compatibility. alias_method :unstyle, :unansi # Alternate term for #ansi. # # @deprecated # May change in future definition. alias_method :color, :ansi # Alias for unansi. # # @deprecated # May change in future definition. alias_method :uncolor, :unansi # Look-up code from chart, or if Integer simply pass through. # Also resolves :random and :on_random. # # @param codes [Array 255 v end end # extend Code end rubyworks-ansi-291cecc/lib/ansi/columns.rb000066400000000000000000000114611516262404200207160ustar00rootroot00000000000000require 'ansi/terminal' module ANSI # class Columns # Create a column-based layout. # # @param [String,Array] list # Multiline String or Array of strings to columnize. # # @param [Hash] options # Options to customize columnization. # # @option options [Fixnum] :columns # Number of columns. # # @option options [Symbol] :align # Column alignment, either :left, :right or :center. # # @option options [String,Fixnum] :padding # String or number or spaces to append to each column. # # The +format+ block MUST return ANSI codes. def initialize(list, options={}, &format) self.list = list self.columns = options[:columns] || options[:cols] self.padding = options[:padding] || 1 self.align = options[:align] || :left #self.ansi = options[:ansi] self.format = format #@columns = nil if @columns == 0 end # def inspect "#<#{self.class}:#{object_id} #{list.inspect} x #{columns}>" end # List layout into columns. Each new line is taken to be # a row-column cell. attr :list def list=(list) case list when ::String @list = list.lines.to_a.map{ |e| e.chomp("\n") } when ::Array @list = list.map{ |e| e.to_s } end end # Default number of columns to display. If nil then the number # of coumns is estimated from the size of the terminal. attr :columns # Set column count ensuring value is either an integer or nil. # The the value given is zero, it will be taken to mean the same # as nil, which means fit-to-screen. def columns=(integer) integer = integer.to_i @columns = (integer.zero? ? nil : integer) end # Padding size to apply to cells. attr :padding # Set padding to string or number (of spaces). def padding=(pad) case pad when Numeric @padding = ' ' * pad.to_i else @padding = pad.to_s end end # Alignment to apply to cells. attr :align # Set alignment ensuring value is a symbol. # # @param [#to_sym] symbol # Either `:right`, `:left` or `:center`. # # @return [Symbol] The given symbol. def align=(symbol) symbol = symbol.to_sym raise ArgumentError, "invalid alignment -- #{symbol.inspect}" \ unless [:left, :right, :center].include?(symbol) @align = symbol end # Formating to apply to cells. attr :format # Set formatting procedure. The procedure must return # ANSI codes, suitable for passing to String#ansi method. def format=(procedure) @format = procedure ? procedure.to_proc : nil end # TODO: Should #to_s also take options and formatting block? # Maybe instead have hoin take all these and leave #to_s bare. # Return string in column layout. The number of columns is determined # by the `columns` property or overriden by +cols+ argument. def to_s(cols=nil) to_s_columns(cols || columns) end # def join(cols=nil) to_s_columns(cols || columns) end private # Layout string lines into columns. # # @todo Put in empty strings for blank cells. # @todo Centering look like it's off by one to the right. # def to_s_columns(columns=nil) lines = list.to_a count = lines.size max = lines.map{ |l| l.size }.max if columns.nil? width = Terminal.terminal_width columns = (width / (max + padding.size)).to_i end rows = [] mod = (count / columns.to_f).to_i mod += 1 if count % columns != 0 lines.each_with_index do |line, index| (rows[index % mod] ||=[]) << line.strip end pad = padding tmp = template(max, pad) str = "" rows.each_with_index do |row, ri| row.each_with_index do |cell, ci| ansi_codes = ansi_formatting(cell, ci, ri) if ansi_codes.empty? str << (tmp % cell) else str << (tmp % cell).ansi(*ansi_codes) end end str.rstrip! str << "\n" end str end # Aligns the cell left or right. def template(max, pad) case align when :center, 'center' offset = " " * (max / 2) "#{offset}%#{max}s#{offset}#{pad}" when :right, 'right' "%#{max}s#{pad}" else "%-#{max}s#{pad}" end end # Used to apply ANSI formatting to each cell. def ansi_formatting(cell, col, row) if @format case @format.arity when 0 f = @format[] when 1 f = @format[cell] when 2 f = @format[col, row] else f = @format[cell, col, row] end else f = nil end [f].flatten.compact end end end rubyworks-ansi-291cecc/lib/ansi/constants.rb000066400000000000000000000010211516262404200212410ustar00rootroot00000000000000module ANSI require 'ansi/chart' # Converts {CHART} and {SPECIAL_CHART} entries into constants. # So for example, the CHART entry for :red becomes: # # ANSI::Constants::RED #=> "\e[31m" # # The ANSI Constants are include into ANSI::Code and can be included # any where will they would be of use. # module Constants CHART.each do |name, code| const_set(name.to_s.upcase, "\e[#{code}m") end SPECIAL_CHART.each do |name, code| const_set(name.to_s.upcase, code) end end end rubyworks-ansi-291cecc/lib/ansi/core.rb000066400000000000000000000005331516262404200201640ustar00rootroot00000000000000require 'ansi/code' require 'ansi/chain' class ::String # def ansi(*codes) if codes.empty? ANSI::Chain.new(self) else ANSI::Code.ansi(self, *codes) end end # def ansi!(*codes) replace(ansi(*codes)) end # def unansi ANSI::Code.unansi(self) end # def unansi! replace(unansi) end end rubyworks-ansi-291cecc/lib/ansi/diff.rb000066400000000000000000000124521516262404200201470ustar00rootroot00000000000000require 'ansi/code' module ANSI # Diff produces colorized differences of two string or objects. # class Diff # Highlights the differnce between two strings. # # This class method is equivalent to calling: # # ANSI::Diff.new(object1, object2).to_a # def self.diff(object1, object2, options={}) new(object1, object2, options={}).to_a end # Setup new Diff object. If the objects given are not Strings # and do not have `#to_str` defined to coerce them to such, then # their `#inspect` methods are used to convert them to strings # for comparison. # # @param [Object] object1 # First object to compare. # # @param [Object] object2 # Second object to compare. # # @param [Hash] options # Options for contoller the way difference is shown. (Not yet used.) # def initialize(object1, object2, options={}) @object1 = convert(object1) @object2 = convert(object2) @diff1, @diff2 = diff_string(@object1, @object2) end # Returns the first object's difference string. def diff1 @diff1 end # Returns the second object's difference string. def diff2 @diff2 end # Returns both first and second difference strings separated by a # new line character. # # @todo Should we use `$/` record separator instead? # # @return [String] Joined difference strings. def to_s "#{@diff1}\n#{@diff2}" end # Returns both first and second difference strings separated by a # the given `separator`. The default is `$/`, the record separator. # # @param [String] separator # The string to use as the separtor between the difference strings. # # @return [String] Joined difference strings. def join(separator=$/) "#{@diff1}#{separator}#{@diff2}" end # Returns the first and second difference strings in an array. # # @return [Array] Both difference strings. def to_a [diff1, diff2] end private # Take two plain strings and produce colorized # versions of each highlighting their differences. # # @param [String] string1 # First string to compare. # # @param [String] string2 # Second string to compare. # # @return [Array] The two difference strings. def diff_string(string1, string2) compare(string1, string2) end # Ensure the object of comparison is a string. If +object+ is not # an instance of String then it wll be converted to one by calling # either #to_str, if the object responds to it, or #inspect. def convert(object) if String === object object elsif object.respond_to?(:to_str) object.to_str else object.inspect end end # Rotation of colors for diff output. COLORS = [:red, :yellow, :magenta] # Take two plain strings and produce colorized # versions of each highlighting their differences. # # @param [String] x # First string to compare. # # @param [String] y # Second string to compare. # # @return [Array] The two difference strings. def compare(x, y) c = common(x, y) a = x.dup b = y.dup oi = 0 oj = 0 c.each_with_index do |m, q| i = a.index(m, oi) j = b.index(m, oj) a[i,m.size] = ANSI.ansi(m, COLORS[q%3]) if i b[j,m.size] = ANSI.ansi(m, COLORS[q%3]) if j oi = i + m.size if i oj = j + m.size if j end return a, b end # Oh, I should have documented this will I knew what the # hell it was doing ;) def common(x,y) c = lcs(x, y) i = x.index(c) j = y.index(c) ix = i + c.size jx = j + c.size if i == 0 l = y[0...j] elsif j == 0 l = x[0...i] else l = common(x[0...i], y[0...j]) end if ix == x.size - 1 r = y[jx..-1] elsif jx = y.size - 1 r = x[ix..-1] else r = common(x[ix..-1], y[jx..-1]) end [l, c, r].flatten.reject{ |s| s.empty? } end # Least common string. def lcs(s1, s2) res="" num=Array.new(s1.size){Array.new(s2.size)} len,ans=0 lastsub=0 s1.scan(/./).each_with_index do |l1,i | s2.scan(/./).each_with_index do |l2,j | unless l1==l2 num[i][j]=0 else (i==0 || j==0)? num[i][j]=1 : num[i][j]=1 + num[i-1][j-1] if num[i][j] > len len = ans = num[i][j] thissub = i thissub -= num[i-1][j-1] unless num[i-1][j-1].nil? if lastsub==thissub res+=s1[i,1] else lastsub=thissub res=s1[lastsub, (i+1)-lastsub] end end end end end res end # Hmm... is this even useful? def lcs_size(s1, s2) num=Array.new(s1.size){Array.new(s2.size)} len,ans=0,0 s1.scan(/./).each_with_index do |l1,i | s2.scan(/./).each_with_index do |l2,j | unless l1==l2 num[i][j]=0 else (i==0 || j==0)? num[i][j]=1 : num[i][j]=1 + num[i-1][j-1] len = ans = num[i][j] if num[i][j] > len end end end ans end end end rubyworks-ansi-291cecc/lib/ansi/hexdump.rb000066400000000000000000000057701516262404200207160ustar00rootroot00000000000000module ANSI require 'ansi/code' # TODO: split dump method into two parts, the first should create a hex table # then the second, #dump method, will print it out. # Create a colorized hex dump of byte string. # # Output looks something like the following, but colorized. # # 000352c0: ed 33 8c 85 6e cc f6 f7 72 79 1c e3 3a b4 c2 c6 |.3..n...ry..:...| # 000352d0: c8 8d d6 ee 3e 68 a1 a5 ae b2 b7 97 a4 1d 5f a7 |....>h........_.| # 000352e0: d8 7d 28 db f6 8a e7 8a 7b 8d 0b bd 35 7d 25 3c |.}(.....{...5}%<| # 000352f0: 8b 3c c8 9d ec 04 85 54 92 a0 f7 a8 ed cf 05 7d |.<.....T.......}| # 00035300: b5 e3 9e 35 f0 79 9f 51 74 e3 60 ee 0f 03 8e 3f |...5.y.Qt.`....?| # 00035310: 05 5b 91 87 e6 48 48 ee a3 77 ae ad 5e 2a 56 a2 |.[...HH..w..^*V.| # 00035320: b6 96 86 f3 3c 92 b3 c8 62 4a 6f 96 10 5c 9c bb |....<...bJo..\..| # # In the future, we will make the colorization more customizable and # allow the groupings to be selectable at 2, 4, 8 or 16. # class HexDump # Printable ASCII codes. ASCII_PRINTABLE = (33..126) # def initialize(options={}) @offset = 0 options.each do |k,v| __send__("#{k}=", v) end @color = true if color.nil? end # Use color? attr_accessor :color # Show index? attr_accessor :index # Offset byte count. attr_accessor :offset # Dump data string as colorized hex table. # # @param data [String] # String to convert to hex and display. # def dump(data) lines = data.to_s.scan(/.{1,16}/m) max_offset = (offset + data.size) / 256 #16 * 16 max_offset_width = max_offset.to_s.size + 1 max_hex_width = 49 #3 * 16 + 1 out = template() off = offset() if index? puts((' ' * max_offset_width) + " 0 1 2 3 4 5 6 7 8 9 A B C D E F\n") end lines.each_with_index do |line, n| offset = off + n * 16 bytes = line.unpack("C*") hex = bytes.map{ |c| "%0.2x" % c }.insert(8, '').join(' ') plain = bytes.map do |c| if ASCII_PRINTABLE.include?(c) c = c.chr else color ? Code::WHITE + Code::STRIKE + '.' + Code::CLEAR : '.' end end.join('') fill = [offset.to_s.rjust(max_offset_width), hex.ljust(max_hex_width), plain] puts(out % fill) end end # Hex dump a random string. # def dump_random(size=64) data = (0..size).map{ rand(255).chr }.join('') dump(data) end # def index? @index end private # Hex dump line template. # # @return [String] hex dump line template def template if color Code::CYAN + "%s: " + Code::YELLOW + "%s " + Code::BLUE + "|" + Code::CLEAR + "%s" + Code::BLUE + "|" + Code::CLEAR else "%s: %s |%s|" end end end end rubyworks-ansi-291cecc/lib/ansi/logger.rb000066400000000000000000000115341516262404200205160ustar00rootroot00000000000000# Ansi::Logger # Copyright (c) 2009 Thomas Sawyer # Copyright (c) 2005 George Moschovitis require "logger" require "time" require "ansi/code" # = ANSI::Logger # # Extended variation of Ruby's standard Logger library that supports # color output. # # log = ANSI::Logger.new # # log.formatter do |severity, timestamp, progname, msg| # ANSI::Logger::SIMPLE_FORMAT % [severity, msg] # end # #-- # TODO: What's all this about then? # # When using debug level logger messages always append 'if $DBG' # at the end. This hack is needed because Ruby does not support # lazy evaluation (lisp macros). #++ class ANSI::Logger < Logger # Some available logging formats. SIMPLE_FORMAT = "%5s: %s\n" DETAILED_FORMAT = "%s %5s: %s\n" # TODO: Not sure I like this approach. class ::Logger #:nodoc: class LogDevice #:nodoc: attr_writer :ansicolor def ansicolor? @ansicolor.nil? ? true : @ansicolor end end end # def ansicolor? @logdev.ansicolor? end # def ansicolor=(on) @logdev.ansicolor = on end # Dictate the way in which this logger should format the # messages it displays. This method requires a block. The # block should return formatted strings given severity, # timestamp, progname and msg. # # === Example # # logger = ANSI::Logger.new # # logger.formatter do |severity, timestamp, progname, msg| # "#{progname}@#{timestamp} - #{severity}::#{msg}" # end # def formatter(&block) self.formatter = block if block super end def styles(options=nil) @styles ||= { :info => [], :warn => [:yellow], :debug => [:cyan], :error => [:red], :fatal => [:bold, :red] } @styles.merge!(options) if options @styles end # def info(progname=nil, &block) return unless info? @logdev.ansicolor? ? info_with_color{ super } : super end # def warn(progname=nil, &block) return unless warn? @logdev.ansicolor? ? warn_with_color{ super } : super end # def debug(progname=nil, &block) return unless debug? @logdev.ansicolor? ? debug_with_color{ super } : super end # def error(progname=nil, &block) return unless error? @logdev.ansicolor? ? error_with_color{ super } : super end # def fatal(progname=nil, &block) return unless error? @logdev.ansicolor? ? fatal_with_color{ super } : super end private def info_with_color #:yield: styles[:info].each{ |s| self << ANSI::Code.send(s) } yield self << ANSI::Code.clear end def warn_with_color #:yield: styles[:warn].each{ |s| self << ANSI::Code.send(s) } yield self << ANSI::Code.clear end def error_with_color #:yield: styles[:error].each{ |s| self << ANSI::Code.send(s) } yield self << ANSI::Code.clear end def debug_with_color #:yield: styles[:debug].each{ |s| self << ANSI::Code.send(s) } yield self << ANSI::Code.clear end def fatal_with_color #:yield: styles[:fatal].each{ |s| self << ANSI::Code.send(s) } yield self << ANSI::Code.clear end end # NOTE: trace is deprecated b/c binding of caller is no longer possible. =begin # Prints a trace message to DEBUGLOG (at debug level). # Useful for emitting the value of variables, etc. Use # like this: # # x = y = 5 # trace 'x' # -> 'x = 5' # trace 'x ** y' # -> 'x ** y = 3125' # # If you have a more complicated value, like an array of # hashes, then you'll probably want to use an alternative # output format. For instance: # # trace 'value', :yaml # # Valid output format values (the _style_ parameter) are: # # :p :inspect # :pp (pretty-print, using 'pp' library) # :s :to_s # :y :yaml :to_yaml (using the 'yaml' library') # # The default is :p. # # CREDITS: # # This code comes straight from the dev-utils Gem. # Author: Gavin Sinclair def trace(expr, style=:p) unless expr.respond_to? :to_str warn "trace: Can't evaluate the given value: #{caller.first}" else raise "FACETS: binding/or_caller is no longer possible" require "facets/core/binding/self/of_caller" Binding.of_caller do |b| value = b.eval(expr.to_str) formatter = TRACE_STYLES[style] || :inspect case formatter when :pp then require 'pp' when :y, :yaml, :to_yaml then require 'yaml' end value_s = value.send(formatter) message = "#{expr} = #{value_s}" lines = message.split(/\n/) indent = " " debug(lines.shift) lines.each do |line| debug(indent + line) end end end end TRACE_STYLES = {} # :nodoc: TRACE_STYLES.update( :pp => :pp_s, :s => :to_s, :p => :inspect, :y => :to_yaml, :yaml => :to_yaml, :inspect => :inspect, :to_yaml => :to_yaml ) =end rubyworks-ansi-291cecc/lib/ansi/mixin.rb000066400000000000000000000143011516262404200203560ustar00rootroot00000000000000module ANSI require 'ansi/code' # This module is designed specifically for mixing into # String-like classes or extending String-like objects. # # Generally speaking the String#ansi method is the more # elegant approach to modifying a string with codes # via a method call. But in some cases this Mixin's design # might be preferable. Indeed, it original intent was # as a compatability layer for the +colored+ gem. module Mixin def bold ; ANSI::Code.bold { to_s } ; end def dark ; ANSI::Code.dark { to_s } ; end def italic ; ANSI::Code.italic { to_s } ; end def underline ; ANSI::Code.underline { to_s } ; end def underscore ; ANSI::Code.underscore { to_s } ; end def blink ; ANSI::Code.blink { to_s } ; end def rapid ; ANSI::Code.rapid { to_s } ; end def reverse ; ANSI::Code.reverse { to_s } ; end def negative ; ANSI::Code.negative { to_s } ; end def concealed ; ANSI::Code.concealed { to_s } ; end def strike ; ANSI::Code.strike { to_s } ; end def black ; ANSI::Code.black { to_s } ; end def red ; ANSI::Code.red { to_s } ; end def green ; ANSI::Code.green { to_s } ; end def yellow ; ANSI::Code.yellow { to_s } ; end def blue ; ANSI::Code.blue { to_s } ; end def magenta ; ANSI::Code.magenta { to_s } ; end def cyan ; ANSI::Code.cyan { to_s } ; end def white ; ANSI::Code.white { to_s } ; end def on_black ; ANSI::Code.on_black { to_s } ; end def on_red ; ANSI::Code.on_red { to_s } ; end def on_green ; ANSI::Code.on_green { to_s } ; end def on_yellow ; ANSI::Code.on_yellow { to_s } ; end def on_blue ; ANSI::Code.on_blue { to_s } ; end def on_magenta ; ANSI::Code.on_magenta { to_s } ; end def on_cyan ; ANSI::Code.on_cyan { to_s } ; end def on_white ; ANSI::Code.on_white { to_s } ; end def black_on_red ; ANSI::Code.black_on_red { to_s } ; end def black_on_green ; ANSI::Code.black_on_green { to_s } ; end def black_on_yellow ; ANSI::Code.black_on_yellow { to_s } ; end def black_on_blue ; ANSI::Code.black_on_blue { to_s } ; end def black_on_magenta ; ANSI::Code.black_on_magenta { to_s } ; end def black_on_cyan ; ANSI::Code.black_on_cyan { to_s } ; end def black_on_white ; ANSI::Code.black_on_white { to_s } ; end def red_on_black ; ANSI::Code.red_on_black { to_s } ; end def red_on_green ; ANSI::Code.red_on_green { to_s } ; end def red_on_yellow ; ANSI::Code.red_on_yellow { to_s } ; end def red_on_blue ; ANSI::Code.red_on_blue { to_s } ; end def red_on_magenta ; ANSI::Code.red_on_magenta { to_s } ; end def red_on_cyan ; ANSI::Code.red_on_cyan { to_s } ; end def red_on_white ; ANSI::Code.red_on_white { to_s } ; end def green_on_black ; ANSI::Code.green_on_black { to_s } ; end def green_on_red ; ANSI::Code.green_on_red { to_s } ; end def green_on_yellow ; ANSI::Code.green_on_yellow { to_s } ; end def green_on_blue ; ANSI::Code.green_on_blue { to_s } ; end def green_on_magenta ; ANSI::Code.green_on_magenta { to_s } ; end def green_on_cyan ; ANSI::Code.green_on_cyan { to_s } ; end def green_on_white ; ANSI::Code.green_on_white { to_s } ; end def yellow_on_black ; ANSI::Code.yellow_on_black { to_s } ; end def yellow_on_red ; ANSI::Code.yellow_on_red { to_s } ; end def yellow_on_green ; ANSI::Code.yellow_on_green { to_s } ; end def yellow_on_blue ; ANSI::Code.yellow_on_blue { to_s } ; end def yellow_on_magenta ; ANSI::Code.yellow_on_magenta { to_s } ; end def yellow_on_cyan ; ANSI::Code.yellow_on_cyan { to_s } ; end def yellow_on_white ; ANSI::Code.yellow_on_white { to_s } ; end def blue_on_black ; ANSI::Code.blue_on_black { to_s } ; end def blue_on_red ; ANSI::Code.blue_on_red { to_s } ; end def blue_on_green ; ANSI::Code.blue_on_green { to_s } ; end def blue_on_yellow ; ANSI::Code.blue_on_yellow { to_s } ; end def blue_on_magenta ; ANSI::Code.blue_on_magenta { to_s } ; end def blue_on_cyan ; ANSI::Code.blue_on_cyan { to_s } ; end def blue_on_white ; ANSI::Code.blue_on_white { to_s } ; end def magenta_on_black ; ANSI::Code.magenta_on_black { to_s } ; end def magenta_on_red ; ANSI::Code.magenta_on_red { to_s } ; end def magenta_on_green ; ANSI::Code.magenta_on_green { to_s } ; end def magenta_on_yellow ; ANSI::Code.magenta_on_yellow { to_s } ; end def magenta_on_blue ; ANSI::Code.magenta_on_blue { to_s } ; end def magenta_on_cyan ; ANSI::Code.magenta_on_cyan { to_s } ; end def magenta_on_white ; ANSI::Code.magenta_on_white { to_s } ; end def cyan_on_black ; ANSI::Code.cyan_on_black { to_s } ; end def cyan_on_red ; ANSI::Code.cyan_on_red { to_s } ; end def cyan_on_green ; ANSI::Code.cyan_on_green { to_s } ; end def cyan_on_yellow ; ANSI::Code.cyan_on_yellow { to_s } ; end def cyan_on_blue ; ANSI::Code.cyan_on_blue { to_s } ; end def cyan_on_magenta ; ANSI::Code.cyan_on_magenta { to_s } ; end def cyan_on_white ; ANSI::Code.cyan_on_white { to_s } ; end def white_on_black ; ANSI::Code.white_on_black { to_s } ; end def white_on_red ; ANSI::Code.white_on_red { to_s } ; end def white_on_green ; ANSI::Code.white_on_green { to_s } ; end def white_on_yellow ; ANSI::Code.white_on_yellow { to_s } ; end def white_on_blue ; ANSI::Code.white_on_blue { to_s } ; end def white_on_magenta ; ANSI::Code.white_on_magenta { to_s } ; end def white_on_cyan ; ANSI::Code.white_on_cyan { to_s } ; end # Move cursor to line and column, insert +self.to_s+ and return to # original positon. def display(line, column=0) result = "\e[s" result << "\e[#{line.to_i};#{column.to_i}H" result << to_s result << "\e[u" result end end end rubyworks-ansi-291cecc/lib/ansi/progressbar.rb000066400000000000000000000144301516262404200215660ustar00rootroot00000000000000# Copyright (C) 2009 Thomas Sawyer # # This library is based on the original ProgressBar # by Satoru Takabayashi. # # ProgressBar Copyright (C) 2001 Satoru Takabayashi require 'ansi/code' module ANSI # = Progressbar # # Progressbar is a text-based progressbar library. # # pbar = Progressbar.new( "Demo", 100 ) # 100.times { pbar.inc } # pbar.finish # class ProgressBar # def initialize(title, total, out=STDERR) @title = title @total = total @out = out @bar_length = 80 @bar_mark = "|" @total_overflow = true @current = 0 @previous = 0 @is_finished = false @start_time = Time.now @format = "%-14s %3d%% %s %s" @format_arguments = [:title, :percentage, :bar, :stat] @styles = {} # yield self if block_given? # show_progress end public attr_accessor :format attr_accessor :format_arguments attr_accessor :styles # def title=(str) @title = str end # def bar_mark=(mark) @bar_mark = String(mark)[0..0] end alias_method :barmark=, :bar_mark= alias_method :mark=, :bar_mark= def total_overflow=(boolv) @total_overflow = boolv ? true : false end # Get rid of warning about Kenrel method being redefined. remove_method :format # Set format and format arguments. def format(format, *arguments) @format = format @format_arguments = *arguments unless arguments.empty? end # Set ANSI styling options. def style(options) @styles = options end # def standard_mode @format = "%-14s %3d%% %s %s" @format_arguments = [:title, :percentage, :bar, :stat] end # def transfer_mode @format = "%-14s %3d%% %s %s" @format_arguments = [:title, :percentage, :bar, :stat_for_file_transfer] end # For backward compatability alias_method :file_transfer_mode, :transfer_mode def finish @current = @total @is_finished = true show_progress end def flush @out.flush end def halt @is_finished = true show_progress end def set(count) if count < 0 raise "invalid count less than zero: #{count}" elsif count > @total if @total_overflow @total = count + 1 else raise "invalid count greater than total: #{count}" end end @current = count show_progress @previous = @current end # def reset @current = 0 @is_finished = false end # def inc(step = 1) @current += step @current = @total if @current > @total show_progress @previous = @current end # def clear @out.print(" " * get_width + eol) end def inspect "(ProgressBar: #{@current}/#{@total})" end private # def convert_bytes(bytes) if bytes < 1024 sprintf("%6dB", bytes) elsif bytes < 1024 * 1000 # 1000kb sprintf("%5.1fKB", bytes.to_f / 1024) elsif bytes < 1024 * 1024 * 1000 # 1000mb sprintf("%5.1fMB", bytes.to_f / 1024 / 1024) else sprintf("%5.1fGB", bytes.to_f / 1024 / 1024 / 1024) end end # def transfer_rate bytes_per_second = @current.to_f / (Time.now - @start_time) sprintf("%s/s", convert_bytes(bytes_per_second)) end # def bytes convert_bytes(@current) end # def format_time(t) t = t.to_i sec = t % 60 min = (t / 60) % 60 hour = t / 3600 sprintf("%02d:%02d:%02d", hour, min, sec); end # # ETA stands for Estimated Time of Arrival. def eta if @current == 0 "ETA: --:--:--" else elapsed = Time.now - @start_time eta = elapsed * @total / @current - elapsed; sprintf("ETA: %s", format_time(eta)) end end # def elapsed elapsed = Time.now - @start_time sprintf("Time: %s", format_time(elapsed)) end # def stat if @is_finished then elapsed else eta end end # def stat_for_file_transfer if @is_finished then sprintf("%s %s %s", bytes, transfer_rate, elapsed) else sprintf("%s %s %s", bytes, transfer_rate, eta) end end # def eol if @is_finished then "\n" else "\r" end end # def bar len = percentage * @bar_length / 100 sprintf("|%s%s|", @bar_mark * len, " " * (@bar_length - len)) end # def percentage if @total.zero? 100 else @current * 100 / @total end end # def title @title[0,13] + ":" end # TODO: Use Terminal.terminal_width instead. def get_width # FIXME: I don't know how portable it is. default_width = 80 begin tiocgwinsz = 0x5413 data = [0, 0, 0, 0].pack("SSSS") if @out.ioctl(tiocgwinsz, data) >= 0 then #rows, cols, xpixels, ypixels = data.unpack("SSSS") cols = data.unpack("SSSS")[1] if cols >= 0 then cols else default_width end else default_width end rescue Exception default_width end end # def show arguments = @format_arguments.map do |method| colorize(send(method), styles[method]) end line = sprintf(@format, *arguments) width = get_width length = ANSI::Code.uncolor{line}.length if length == width - 1 @out.print(line + eol) elsif length >= width @bar_length = [@bar_length - (length - width + 1), 0].max @bar_length == 0 ? @out.print(line + eol) : show else #line.length < width - 1 @bar_length += width - length + 1 show end end # def show_progress if @total.zero? cur_percentage = 100 prev_percentage = 0 else cur_percentage = (@current * 100 / @total).to_i prev_percentage = (@previous * 100 / @total).to_i end if cur_percentage > prev_percentage || @is_finished show end end # def colorize(part, style) return part unless style #[style].flatten.inject(part){ |pt, st| ANSI::Code.ansi(pt, *st) } ANSI::Code.ansi(part, *style) end end # Progressbar = ProgressBar #:nodoc: end rubyworks-ansi-291cecc/lib/ansi/string.rb000066400000000000000000000137661516262404200205560ustar00rootroot00000000000000require 'ansi/code' #require 'ansi/layout/split' # Create a new Ansi::String object. def ANSI.string(str) ANSI::String.new(str) end # IMPORTANT! ANSI::String is experimental!!! # # ANSI::String stores a regular string (`@text`) and an associative # array that ties a character index to an ANSI code (`marks`). # For example is we have the string: # # "Big Apple" # # And applied the color red to it, the marks list would be: # # [[0, :red], [9, :clear]] # # TODO: In the future we may be able to subclass String, # instead of delegating via @text, but not until it is more # compatible. # class ANSI::String CLR = ANSI::Code::CLEAR attr :text attr :marks # New Ansi::String def initialize(text=nil, marks=nil) @text = (text || '').to_s @marks = marks || [] yield(self) if block_given? end # Convert Ansi::String object to normal String. # This converts the intental markup codes to ANSI codes. def to_s s = text.dup m = marks.sort do |a,b| v = b[0] <=> a[0] if v == 0 (b[1] == :clear or b[1] == :reset) ? -1 : 1 else v end end m.each do |(index, code)| s.insert(index, ANSI::Code.__send__(code)) end #s << CLR unless s =~ /#{Regexp.escape(CLR)}$/ # always end with a clear s end # ANSI::String is a type of String. alias_method :to_str, :to_s # The size of the base text. def size ; text.size ; end # Upcase the string. def upcase ; self.class.new(text.upcase, marks) ; end def upcase! ; text.upcase! ; end # Downcase the string. def downcase ; self.class.new(text.downcase, marks) ; end def downcase! ; text.upcase! ; end # Add one String to another, or to a regular String. def +(other) case other when ANSI::String ntext = text + other.text nmarks = marks.dup omarks = shift_marks(0, text.size, other.marks) omarks.each{ |(i, c)| nmarks << [i,c] } else ntext = text + other.to_s nmarks = marks.dup end self.class.new(ntext, nmarks) end # #def |(other) # Split.new(self, other) #end # #def lr(other, options={}) # Split.new(self, other, options) #end # slice def slice(*args) if args.size == 2 index, len = *args endex = index+len new_text = text[index, len] new_marks = [] marks.each do |(i, v)| new_marks << [i, v] if i >= index && i < endex end self.class.new(new_text, new_marks) elsif args.size == 1 rng = args.first case rng when Range index, endex = rng.begin, rng.end new_text = text[rng] new_marks = [] marks.each do |(i, v)| new_marks << [i, v] if i >= index && i < endex end self.class.new(new_text, new_marks) else nm = marks.select do |(i, v)| #marks[0] == rng or ( marks[0] == rng + 1 && [:clear, :reset].include?(marks[1]) ) i == rng or ( i == rng + 1 && [:clear, :reset].include?(v) ) end self.class.new(text[rng,1], nm) end else raise ArgumentError end end # alias_method :[], :slice # This is more limited than the normal String method. # It does not yet support a block, and +replacement+ # won't substitue for \1, \2, etc. # # TODO: block support. def sub!(pattern, replacement=nil, &block) mark_changes = [] text = @text.sub(pattern) do |s| index = $~.begin(0) replacement = block.call(s) if block_given? delta = (replacement.size - s.size) mark_changes << [index, delta] replacement end marks = @marks mark_changes.each do |index, delta| marks = shift_marks(index, delta, marks) end @text = text @marks = marks self end # See #sub!. def sub(pattern,replacement=nil, &block) dup.sub!(pattern, replacement, &block) end # def gsub!(pattern, replacement=nil, &block) mark_changes = [] mark_additions = [] text = @text.gsub(pattern) do |s| index = $~.begin(0) replacement = block.call(self.class.new(s)) if block_given? if self.class===replacement adj_marks = replacement.marks.map{ |(i,c)| [i+index,c] } mark_additions.concat(adj_marks) replacement = replacement.text end delta = (replacement.size - s.size) mark_changes << [index, delta] replacement end marks = @marks mark_changes.each do |(index, delta)| marks = shift_marks(index, delta, marks) end marks.concat(mark_additions) @text = text @marks = marks self end # See #gsub!. def gsub(pattern, replacement=nil, &block) dup.gsub!(pattern, replacement, &block) end # def ansi(code) m = marks.dup m.unshift([0, code]) m.push([size, :clear]) self.class.new(text, m) end alias_method :color, :ansi # def ansi!(code) marks.unshift([0, code]) marks.push([size, :clear]) end alias_method :color!, :ansi! def red ; color(:red) ; end def green ; color(:green) ; end def blue ; color(:blue) ; end def black ; color(:black) ; end def magenta ; color(:magenta) ; end def yellow ; color(:yellow) ; end def cyan ; color(:cyan) ; end def bold ; ansi(:bold) ; end def underline ; ansi(:underline) ; end def red! ; color!(:red) ; end def green! ; color!(:green) ; end def blue! ; color!(:blue) ; end def black! ; color!(:black) ; end def magenta! ; color!(:magenta) ; end def yellow! ; color!(:yellow) ; end def cyan! ; color!(:cyan) ; end def bold! ; ansi!(:bold) ; end def underline! ; ansi!(:underline) ; end private # def shift_marks(index, delta, marks=nil) new_marks = [] (marks || @marks).each do |(i, c)| case i <=> index when -1 new_marks << [i, c] when 0, 1 new_marks << [i+delta, c] end end new_marks end # def shift_marks!(index, delta) @marks.replace(shift_marks(index, delta)) end end rubyworks-ansi-291cecc/lib/ansi/table.rb000066400000000000000000000073361516262404200203330ustar00rootroot00000000000000require 'ansi/core' require 'ansi/terminal' module ANSI class Table # The Table class can be used to output nicely formatted # tables with division lines and alignment. # # table - array of array # # options[:align] - align :left or :right # options[:padding] - space to add to each cell # options[:fit] - fit to screen width # options[:border] - # # The +format+ block must return ANSI codes to apply # to each cell. # # Other Implementations: # # * http://github.com/visionmedia/terminal-table # * http://github.com/aptinio/text-table # # TODO: Support for table headers and footers. def initialize(table, options={}, &format) @table = table @padding = options[:padding] || 0 @align = options[:align] @fit = options[:fit] @border = options[:border] #@ansi = [options[:ansi]].flatten @format = format @pad = " " * @padding end # attr_accessor :table # Fit to scree width. attr_accessor :fit # attr_accessor :padding # attr_accessor :align # attr_accessor :format # attr_accessor :border # def to_s #(fit=false) #row_count = table.size #col_count = table[0].size max = max_columns(fit) div = dividing_line top = div #.gsub('+', ".") bot = div #.gsub('+', "'") body = [] table.each_with_index do |row, r| body_row = [] row.each_with_index do |cell, c| t = cell_template(max[c]) s = t % cell.to_s body_row << apply_format(s, cell, c, r) end body << "| " + body_row.join(' | ') + " |" end if border body = body.join("\n#{div}\n") else body = body.join("\n") end "#{top}\n#{body}\n#{bot}\n" end private # TODO: look at the lines and figure out how many columns will fit def fit_width width = Terminal.terminal_width ((width.to_f / column_size) - (padding + 3)).to_i end # Calculate the maximun column sizes. # # @return [Array] maximum size for each column def max_columns(fit=false) max = Array.new(column_size, 0) table.each do |row| row.each_with_index do |col, index| col = col.to_s col = col.unansi if fit max[index] = [max[index], col.size, fit_width].max else max[index] = [max[index], col.size].max end end end max end # Number of columns based on the first row of table. # # @return [Integer] number of columns def column_size table.first.size end # def cell_template(max) case align when :right, 'right' "#{@pad}%#{max}s" else "%-#{max}s#{@pad}" end end # TODO: make more efficient def dividing_line tmp = max_columns(fit).map{ |m| "%#{m}s" }.join(" | ") tmp = "| #{tmp} |" lin = (tmp % (['-'] * column_size)).gsub(/[^\|]/, '-').gsub('|', '+') lin end #def dividing_line_top # dividing_line.gsub('+', '.') #end #def dividing_line_bottom # dividing_line.gsub('+', "'") #end # def apply_format(str, cell, col, row) if @format str.ansi(*ansi_formating(cell, col, row)) else str end end # def ansi_formating(cell, col, row) if @format case @format.arity when 0 f = @format[] when 1 f = @format[cell] when 2 f = @format[row, col] else f = @format[cell, row, col] end else f = nil end [f].flatten.compact end end end rubyworks-ansi-291cecc/lib/ansi/terminal.rb000066400000000000000000000015531516262404200210520ustar00rootroot00000000000000module ANSI # = Terminal # # This library is based of HighLine's SystemExtensions # by James Edward Gray II. # # Copyright 2006 Gray Productions # # Distributed under the tems of the # {Ruby software license}[http://www.ruby-lang.org/en/LICENSE.txt]. module Terminal module_function modes = %w{win32 termios curses stty} # This section builds character reading and terminal size functions # to suit the proper platform we're running on. # # Be warned: Here be dragons! # begin require 'ansi/terminal/' + (mode = modes.shift) CHARACTER_MODE = mode rescue LoadError retry end # Get the width of the terminal window. def terminal_width terminal_size.first end # Get the height of the terminal window. def terminal_height terminal_size.last end end end rubyworks-ansi-291cecc/lib/ansi/terminal/000077500000000000000000000000001516262404200205215ustar00rootroot00000000000000rubyworks-ansi-291cecc/lib/ansi/terminal/curses.rb000066400000000000000000000006141516262404200223530ustar00rootroot00000000000000module ANSI module Terminal require 'curses' module_function #CHARACTER_MODE = "curses" # For Debugging purposes only. # # Curses savvy getc(). # def get_character(input = STDIN) Curses.getch() end def terminal_size Curses.init_screen w, r = Curses.cols, Curses.lines Curses.close_screen return w, r end end end rubyworks-ansi-291cecc/lib/ansi/terminal/stty.rb000066400000000000000000000024141516262404200220520ustar00rootroot00000000000000module ANSI module Terminal module_function #COLS_FALLBACK = 80 #ROWS_FALLBACK = 25 #CHARACTER_MODE = "stty" # For Debugging purposes only. # # Unix savvy getc(). (second choice) # # *WARNING*: This method requires the external "stty" program! # def get_character(input = STDIN) raw_no_echo_mode begin input.getc ensure restore_mode end end # # Switched the input mode to raw and disables echo. # # *WARNING*: This method requires the external "stty" program! # def raw_no_echo_mode @state = `stty -g` system "stty raw -echo cbreak isig" end # # Restores a previously saved input mode. # # *WARNING*: This method requires the external "stty" program! # def restore_mode system "stty #{@state}" end # A Unix savvy method to fetch the console columns, and rows. def terminal_size if /solaris/ =~ RUBY_PLATFORM && (`stty` =~ /\brows = (\d+).*\bcolumns = (\d+)/) w, r = [$2, $1] else w, r = `stty size`.split.reverse end w = `tput cols` unless w # last ditch effort to at least get width w = w.to_i if w r = r.to_i if r return w, r end end end rubyworks-ansi-291cecc/lib/ansi/terminal/termios.rb000066400000000000000000000033421516262404200225320ustar00rootroot00000000000000module ANSI module Terminal require "termios" # Unix, first choice. module_function #CHARACTER_MODE = "termios" # For Debugging purposes only. # # Unix savvy getc(). (First choice.) # # *WARNING*: This method requires the "termios" library! # def get_character( input = STDIN ) old_settings = Termios.getattr(input) new_settings = old_settings.dup new_settings.c_lflag &= ~(Termios::ECHO | Termios::ICANON) new_settings.c_cc[Termios::VMIN] = 1 begin Termios.setattr(input, Termios::TCSANOW, new_settings) input.getc ensure Termios.setattr(input, Termios::TCSANOW, old_settings) end end # A Unix savvy method to fetch the console columns, and rows. def terminal_size if /solaris/ =~ RUBY_PLATFORM && (`stty` =~ /\brows = (\d+).*\bcolumns = (\d+)/) w, r = [$2, $1] else w, r = `stty size`.split.reverse end w = `tput cols` unless w # last ditch effort to at least get width w = w.to_i if w r = r.to_i if r return w, r end # Console screen width (taken from progress bar) # # NOTE: Don't know how portable #screen_width is. # TODO: How to fit into system? # def screen_width(out=STDERR) default_width = ENV['COLUMNS'] || 76 begin tiocgwinsz = 0x5413 data = [0, 0, 0, 0].pack("SSSS") if out.ioctl(tiocgwinsz, data) >= 0 then rows, cols, xpixels, ypixels = data.unpack("SSSS") if cols >= 0 then cols else default_width end else default_width end rescue Exception default_width end end end end rubyworks-ansi-291cecc/lib/ansi/terminal/win32.rb000066400000000000000000000057311516262404200220160ustar00rootroot00000000000000module ANSI module Terminal # Cygwin will look like Windows, but we want to treat it like a Posix OS: raise LoadError, "Cygwin is a Posix OS." if RUBY_PLATFORM =~ /\bcygwin\b/i require "Win32API" # See if we're on Windows. module_function #CHARACTER_MODE = "Win32API" # For Debugging purposes only. # # Windows savvy getc(). # # def get_character( input = STDIN ) @stdin_handle ||= GetStdHandle(STD_INPUT_HANDLE) begin SetConsoleEcho(@stdin_handle, false) input.getc ensure SetConsoleEcho(@stdin_handle, true) end end # A Windows savvy method to fetch the console columns, and rows. def terminal_size stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE) bufx, bufy, curx, cury, wattr, left, top, right, bottom, maxx, maxy = GetConsoleScreenBufferInfo(stdout_handle) return right - left + 1, bottom - top + 1 end # windows savvy console echo toggler def SetConsoleEcho( console_handle, on ) mode = GetConsoleMode(console_handle) # toggle the console echo bit if on mode |= ENABLE_ECHO_INPUT else mode &= ~ENABLE_ECHO_INPUT end ok = SetConsoleMode(console_handle, mode) end # win32 console APIs STD_INPUT_HANDLE = -10 STD_OUTPUT_HANDLE = -11 STD_ERROR_HANDLE = -12 ENABLE_PROCESSED_INPUT = 0x0001 ENABLE_LINE_INPUT = 0x0002 ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002 ENABLE_ECHO_INPUT = 0x0004 ENABLE_WINDOW_INPUT = 0x0008 ENABLE_MOUSE_INPUT = 0x0010 ENABLE_INSERT_MODE = 0x0020 ENABLE_QUICK_EDIT_MODE = 0x0040 @@apiGetStdHandle = nil @@apiGetConsoleMode = nil @@apiSetConsoleMode = nil @@apiGetConsoleScreenBufferInfo = nil def GetStdHandle( handle_type ) @@apiGetStdHandle ||= Win32API.new( "kernel32", "GetStdHandle", ['L'], 'L' ) @@apiGetStdHandle.call( handle_type ) end def GetConsoleMode( console_handle ) @@apiGetConsoleMode ||= Win32API.new( "kernel32", "GetConsoleMode", ['L', 'P'], 'I' ) mode = ' ' * 4 @@apiGetConsoleMode.call(console_handle, mode) mode.unpack('L')[0] end def SetConsoleMode( console_handle, mode ) @@apiSetConsoleMode ||= Win32API.new( "kernel32", "SetConsoleMode", ['L', 'L'], 'I' ) @@apiSetConsoleMode.call(console_handle, mode) != 0 end def GetConsoleScreenBufferInfo( console_handle ) @@apiGetConsoleScreenBufferInfo ||= Win32API.new( "kernel32", "GetConsoleScreenBufferInfo", ['L', 'P'], 'L' ) format = 'SSSSSssssSS' buf = ([0] * format.size).pack(format) @@apiGetConsoleScreenBufferInfo.call(console_handle, buf) buf.unpack(format) end end end rubyworks-ansi-291cecc/lib/ansi/version.rb000066400000000000000000000000441516262404200207160ustar00rootroot00000000000000module ANSI VERSION = '1.6.0' end rubyworks-ansi-291cecc/test/000077500000000000000000000000001516262404200161655ustar00rootroot00000000000000rubyworks-ansi-291cecc/test/case_ansicode.rb000066400000000000000000000012771516262404200213010ustar00rootroot00000000000000require 'test_helper' require 'ansi/code' testcase ANSI::Code do method :red do test do str = ANSI::Code.red out = "\e[31m" out.assert == str end test "with block notation" do str = ANSI::Code.red { "Hello" } out = "\e[31mHello\e[0m" out.assert == str end end method :blue do test do str = ANSI::Code.blue out = "\e[34m" out.assert == str end test "with block notation" do str = ANSI::Code.blue { "World" } out = "\e[34mWorld\e[0m" out.assert == str end end method :hex do test do str = ANSI::Code.hex("#000000") out = "0" out.assert == str end end end rubyworks-ansi-291cecc/test/case_bbcode.rb000066400000000000000000000021611516262404200207230ustar00rootroot00000000000000require 'test_helper' require 'ansi/bbcode' testcase ANSI::BBCode do class_method :bbcode_to_ansi do test do str = "this is [COLOR=red]red[/COLOR], this is [B]bold[/B]" out = "this is \e[0;31mred\e[0m, this is \e[1mbold\e[0m\n" out.assert == ANSI::BBCode.bbcode_to_ansi(str) end end class_method :bbcode_to_html do test do str = "this is [COLOR=red]red[/COLOR], this is [B]bold[/B]" out = "this is red, this is bold
    \n" out.assert == ANSI::BBCode.bbcode_to_html(str) end end class_method :ansi_to_html do test do str = "this is \e[0;31mred\e[0m, this is \e[1mbold\e[0m\n" + "this is a line without any ansi code\n" + "this is \e[0;31mred\e[0m, this is \e[1mbold\e[0m\n" out = "this is red, this is bold
    \n" + "this is a line without any ansi code
    \n" + "this is red, this is bold
    \n" out.assert == ANSI::BBCode.ansi_to_html(str) end end end rubyworks-ansi-291cecc/test/case_mixin.rb000066400000000000000000000010221516262404200206240ustar00rootroot00000000000000require 'test_helper' require 'ansi/mixin' testcase ANSI::Mixin do # TODO: subclass class ::String include ANSI::Mixin end method :red do test do str = "Hello".red out = "\e[31mHello\e[0m" out.assert == str end end method :blue do test do str = "World".blue out = "\e[34mWorld\e[0m" out.assert == str end end method :display do test do str = "Hello".display(4,10) out = "\e[s\e[4;10HHello\e[u" out.assert == str end end end rubyworks-ansi-291cecc/test/case_progressbar.rb000066400000000000000000000005761516262404200220460ustar00rootroot00000000000000require 'test_helper' require 'stringio' require 'ansi/progressbar' testcase ANSI::Progressbar do method :initialize do test do stio = StringIO.new pbar = ANSI::Progressbar.new("Test Bar", 10, stio) do |b| b.style(:title => [:red], :bar=>[:blue]) end 10.times do |i| sleep 0.1 pbar.inc end true end end end rubyworks-ansi-291cecc/test/test_helper.rb000066400000000000000000000000361516262404200210270ustar00rootroot00000000000000require 'lemon' require 'ae' rubyworks-ansi-291cecc/work/000077500000000000000000000000001516262404200161705ustar00rootroot00000000000000rubyworks-ansi-291cecc/work/NOTES.md000066400000000000000000000001341516262404200174000ustar00rootroot00000000000000= DEVELOPMENT NOTES == Tweaks Branch The `tweaks` branch needs to be merged into master. rubyworks-ansi-291cecc/work/benchmarks/000077500000000000000000000000001516262404200203055ustar00rootroot00000000000000rubyworks-ansi-291cecc/work/benchmarks/string_vs_block.rb000066400000000000000000000003161516262404200240220ustar00rootroot00000000000000require 'benchmark' require 'ansi/code' n = 50000 Benchmark.bmbm(10) do |x| x.report("string:"){ n.times{|i| ANSI::Code.red(i.to_s) } } x.report("block :"){ n.times{|i| ANSI::Code.red{i.to_s} } } end rubyworks-ansi-291cecc/work/consider/000077500000000000000000000000001516262404200177765ustar00rootroot00000000000000rubyworks-ansi-291cecc/work/consider/highlight.rb000066400000000000000000000017521516262404200222770ustar00rootroot00000000000000require 'ansi/code' file = ARGV.first text = File.read(file) close = ANSI::Code.clear def uncolored(str) ANSI::Code.uncolored(str) end colors = { :dot => ANSI::Code.red, :cash => ANSI::Code.green, :at => ANSI::Code.cyan, :fn => ANSI::Code.bold + ANSI::Code.blue, :cap => ANSI::Code.blue, :sharp => ANSI::Code.white, :quote => ANSI::Code.red, } work = text.dup # xxx( text.gsub!(/(\W)(\w+?)(?=\()/){ $1 + colors[:fn] + $2 + close } # .xxx text.gsub!(/\.(\w+?)(?=\W)/){ colors[:dot] + '.' + $1 + close } # $xxx text.gsub!(/(\$\w+?)(?=\W)/){ colors[:cash] + $1 + close } # @xxx text.gsub!(/(\$\w+?)(?=\W)/){ colors[:at] + $1 + close } # #xxx text.gsub!(/\#(.*?)$/){ colors[:sharp] + '#' + uncolored($1) + close } # XXX text.gsub!(/([A-Z_]+?)(?=\W)/){ colors[:cap] + $1 + close } # 'xxx' text.gsub!(/(['"].*?["'])/){ colors[:quote] + uncolored($1) + close } # #xxx text.gsub!(/^(\s+)(\#.*?)$/){ $1 + colors[:sharp] + '#' + uncolored($2) + close } $stdout << text rubyworks-ansi-291cecc/work/consider/string.rd000066400000000000000000000040511516262404200216330ustar00rootroot00000000000000= Clio::String This is a unit test specification for the Clio::String class. This class is intended to provide a very convenient way to output colorful and aligned text to a shell console. Require the Clio String library. require 'clio/string' Define a few regular strings for comparison. @s1 = "Hi how are you." @s2 = "Fine thanks." Define the equivalent Clio strings. @c1 = Clio.string("Hi how are you.") @c2 = Clio.string("Fine thanks.") Clio::String#ansi is used to wrap the current string in an ANSI code *bracket*, ie. prepending with the given ANSI code and appending with the ANSI escape code. y = @c1.ansi(:red) x = "\e[31mHi how are you.\e[0m" y.to_s.should == x Some methods are delegated directly to the underying string, as they do not effect any ANSI codes have been applied. y = @c1.ansi(:red).upcase x = "\e[31mHI HOW ARE YOU.\e[0m" y.to_s.should == x Shortcut methods are provided for most ANSI Codes, such as Clio::String#red. y = @c1.red x = "\e[31mHi how are you.\e[0m" y.to_s.should == x Clio::String#[] will return the character at a gven index. This works like Ruby 1.9, so no size parameter is needed. y = @c1[0] x = @s1[0,1] y.to_s.should == x But the size parameter can be given too. y = @c1[0,3] x = @s1[0,3] y.to_s.should == x A Range works too. y = @c1[0..3] x = @s1[0..3] y.to_s.should == x Clio::String#+ works just like a regular String. y = @c1 + @c2 x = @s1 + @s2 y.to_s.should == x Complex cases with ANSI codes work as expected. s1 = Clio.string("a").red s2 = Clio.string("b").blue y = s1 + s2 x = "\e[31ma\e[0m\e[34mb\e[0m" y.to_s.should == x Method #sub can replace a substring. y = @c1.sub('Hi', 'Hello') x = "Hello how are you." y.to_s.assert == x Method #gsub! can replace many substrings. s1 = Clio.string("axax").red s2 = Clio.string("axax").blue y = s1 + s2 y.to_s.assert == "\e[31maxax\e[0m\e[34maxax\e[0m" y.gsub!('x', 'y') y.to_s.assert == "\e[31mayay\e[0m\e[34mayay\e[0m" This specification is not complete, but it is a good start. rubyworks-ansi-291cecc/work/deprecated/000077500000000000000000000000001516262404200202705ustar00rootroot00000000000000rubyworks-ansi-291cecc/work/deprecated/ansi.rbz000066400000000000000000000013211516262404200217360ustar00rootroot00000000000000# ANSI Module provides a Bezel interface as follows: # # ANSI = lib('ansi', '1.2.6') # # module MyAPP # include ANSI # end # # Examples # # def hello_world # puts ansi("Hello World", :red) # end # # # automatically included with ANSI 1.3. # def ansi(string, *codes) # ANSI::Code.ansi(string, *codes) # end # # Or # # def hello_world # puts "Hello World".ansi(:red) # end # # NOTE: Core extensions need stable interfaces! # module ANSI; end import 'ansi/code' import 'ansi/bbcode' import 'ansi/columns' import 'ansi/diff' import 'ansi/logger' import 'ansi/mixin' import 'ansi/progressbar' import 'ansi/string' import 'ansi/table' import 'ansi/terminal' rubyworks-ansi-291cecc/work/deprecated/task/000077500000000000000000000000001516262404200212325ustar00rootroot00000000000000rubyworks-ansi-291cecc/work/deprecated/task/demo.ergo000066400000000000000000000004311516262404200230320ustar00rootroot00000000000000#!/usr/bin/env ruby desc "run demos" rule "demo/*.md" => :run_demo rule "lib/**/*.rb" => :run_all def run_demo(*demos) shell "bundle exec qed -Ilib " + demos.join(' ') end def run_all shell "bundle exec qed -Ilib demo/*.md" end #task("demo") { shell "qed -Ilib qed/" } rubyworks-ansi-291cecc/work/deprecated/task/index.ergo000066400000000000000000000001451516262404200232170ustar00rootroot00000000000000#!/usr/bin/env ruby desc "update index file" rule 'Index.yml' do shell "index -u Index.yml" end rubyworks-ansi-291cecc/work/deprecated/task/syckle-hooks/000077500000000000000000000000001516262404200236455ustar00rootroot00000000000000rubyworks-ansi-291cecc/work/deprecated/task/syckle-hooks/pre-generate.rb000066400000000000000000000007631516262404200265560ustar00rootroot00000000000000#!/usr/bin/env ruby file = "lib/#{project.metadata.name}/version.rb" line = [] line << "module ANSI" line << " VERSION = '#{project.version}'" line << " DATE = '#{Time.new.strftime("%Y-%m-%d")}'" #project.profile.to_h.each do |key, value| # next if key == "manifest" # line << " #{key.upcase} = #{value.inspect}" #end line << "end" text = line.join("\n") if !exist?(file) || read(file) != text write(file, text) report "Updated #{file}" else report "Already current #{file}" end rubyworks-ansi-291cecc/work/deprecated/task/test.ergo000066400000000000000000000010641516262404200230700ustar00rootroot00000000000000#!/usr/bin/env ruby desc "run unit tests" rule 'test/helper.rb' => :test_all rule 'test/case_*.rb' => :test rule /^lib\/(.*?)\.rb$/ => :test_match rule /^lib\/ansi\/(.*?)\.rb$/ => :test_match def test_all test *Dir['test/test_*.rb'] end def test_match(m) test "test/case_#{m[1]}" end def test(*paths) shell "bundle exec rubytest #{gem_opt} -Ilib:test " + paths.flatten.join(' ') end def gem_opt defined?(::Gem) ? "-rubygems" : "" end #Signal.trap('QUIT') { test tests } # Ctrl-\ #Signal.trap('INT' ) { abort("\n") } # Ctrl-C rubyworks-ansi-291cecc/work/deprecated/task/test.watchr000066400000000000000000000011761516262404200234300ustar00rootroot00000000000000#!/usr/bin/env ruby watch( '^test.*/test_.*\.rb' ) { |m| test m[0] } watch( '^lib/(.*)\.rb' ) { |m| test "test/case_#{m[1]}.rb" } watch( '^lib/ansi/(.*)\.rb' ) { |m| test "test/case_#{m[1]}.rb" } watch( '^test/test_helper\.rb' ) { test tests } Signal.trap('QUIT') { test tests } # Ctrl-\ Signal.trap('INT' ) { abort("\n") } # Ctrl-C def test(*paths) run "ruby-test #{gem_opt} -Ilib:test #{paths.flatten.join(' ')}" end def tests Dir['test/**/case_*.rb'] end def run(cmd) puts cmd system cmd end def gem_opt defined?(Gem) ? "-rubygems" : "" end rubyworks-ansi-291cecc/work/reference/000077500000000000000000000000001516262404200201265ustar00rootroot00000000000000rubyworks-ansi-291cecc/work/reference/ansicode.rb000066400000000000000000000146431516262404200222500ustar00rootroot00000000000000# = ANSICode # # Module which makes it very easy to use ANSI codes. # These are esspecially nice for beautifying shell output. # # include ANSICode # # p red, "Hello", blue, "World" # => "\e[31mHello\e[34mWorld" # # p red { "Hello" } + blue { "World" } # => "\e[31mHello\e[0m\e[34mWorld\e[0m" # # == Supported ANSI Comands # # The following is a list of supported codes. # # save # restore # clear_screen # cls # synonym for :clear_screen # clear_line # clr # synonym for :clear_line # move # up # down # left # right # display # # clear # reset # synonym for :clear # bold # dark # italic # not widely implemented # underline # underscore # synonym for :underline # blink # rapid_blink # not widely implemented # negative # no reverse because of String#reverse # concealed # strikethrough # not widely implemented # # black # red # green # yellow # blue # magenta # cyan # white # # on_black # on_red # on_green # on_yellow # on_blue # on_magenta # on_cyan # on_white # # == Authors # # * Florian Frank # * Thomas Sawyer # # == Speical Thanks # # Special thanks to Florian Frank. ANSICode is a partial adaptation # of ANSIColor, Copyright (c) 2002 Florian Frank, LGPL. # # == Todo # # * Need to add rest of ANSI codes. Include modes? # * Re-evaluate how color/yielding methods are defined. # * Maybe up, down, right, left should have yielding methods too? # # == Copying # # Copyright (c) 2004 Florian Frank, Thomas Sawyer # # Ruby License # # This module is free software. You may use, modify, and/or redistribute this # software under the same terms as Ruby. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. # = ANSICode # # Module which makes it very easy to use ANSI codes. # These are esspecially nice for beautifying shell output. # # include ANSICode # # p red, "Hello", blue, "World" # => "\e[31mHello\e[34mWorld" # # p red { "Hello" } + blue { "World" } # => "\e[31mHello\e[0m\e[34mWorld\e[0m" # # == Supported ANSI Comands # # The following is a list of supported codes. # # save # restore # clear_screen # cls # synonym for :clear_screen # clear_line # clr # synonym for :clear_line # move # up # down # left # right # display # # clear # reset # synonym for :clear # bold # dark # italic # not widely implemented # underline # underscore # synonym for :underline # blink # rapid_blink # not widely implemented # negative # no reverse because of String#reverse # concealed # strikethrough # not widely implemented # # black # red # green # yellow # blue # magenta # cyan # white # # on_black # on_red # on_green # on_yellow # on_blue # on_magenta # on_cyan # on_white # module ANSICode extend self # Save current cursor positon. def save "\e[s" end # Restore saved cursor positon. def restore "\e[u" end # Clear the screen and move cursor to home. def clear_screen "\e[2J" end alias_method :cls, :clear_screen # Clear to the end of the current line. def clear_line "\e[K" end alias_method :clr, :clear_line #-- #def position # "\e[#;#R" #end #++ # Move curose to line and column. def move( line, column=0 ) "\e[#{line.to_i};#{column.to_i}H" end # Move cursor up a specificed number of spaces. def up( spaces=1 ) "\e[#{spaces.to_i}A" end # Move cursor down a specificed number of spaces. def down( spaces=1 ) "\e[#{spaces.to_i}B" end # Move cursor left a specificed number of spaces. def left( spaces=1 ) "\e[#{spaces.to_i}D" end # Move cursor right a specificed number of spaces. def right( spaces=1 ) "\e[#{spaces.to_i}C" end # Like +move+ but returns to original positon # after yielding block or adding string argument. def display( line, column=0, string=nil ) #:yield: result = "\e[s" result << "\e[#{line.to_i};#{column.to_i}H" if block_given? result << yield result << "\e[u" elsif string result << string result << "\e[u" elsif respond_to?(:to_str) result << self result << "\e[u" end return result end # Define color codes. def self.define_ansicolor_method(name,code) class_eval <<-HERE def #{name.to_s}(string = nil) result = "\e[#{code}m" if block_given? result << yield result << "\e[0m" elsif string result << string result << "\e[0m" elsif respond_to?(:to_str) result << self result << "\e[0m" end return result end HERE end @@colors = [ [ :clear , 0 ], [ :reset , 0 ], # synonym for :clear [ :bold , 1 ], [ :dark , 2 ], [ :italic , 3 ], # not widely implemented [ :underline , 4 ], [ :underscore , 4 ], # synonym for :underline [ :blink , 5 ], [ :rapid_blink , 6 ], # not widely implemented [ :negative , 7 ], # no reverse because of String#reverse [ :concealed , 8 ], [ :strikethrough, 9 ], # not widely implemented [ :black , 30 ], [ :red , 31 ], [ :green , 32 ], [ :yellow , 33 ], [ :blue , 34 ], [ :magenta , 35 ], [ :cyan , 36 ], [ :white , 37 ], [ :on_black , 40 ], [ :on_red , 41 ], [ :on_green , 42 ], [ :on_yellow , 43 ], [ :on_blue , 44 ], [ :on_magenta , 45 ], [ :on_cyan , 46 ], [ :on_white , 47 ], ] @@colors.each do |c, v| define_ansicolor_method(c, v) end ColoredRegexp = /\e\[([34][0-7]|[0-9])m/ def uncolored(string = nil) if block_given? yield.gsub(ColoredRegexp, '') elsif string string.gsub(ColoredRegexp, '') elsif respond_to?(:to_str) gsub(ColoredRegexp, '') else '' end end module_function def colors @@colors.map { |c| c[0] } end end rubyworks-ansi-291cecc/work/reference/console/000077500000000000000000000000001516262404200215705ustar00rootroot00000000000000rubyworks-ansi-291cecc/work/reference/console/.gitignore000066400000000000000000000000041516262404200235520ustar00rootroot00000000000000doc rubyworks-ansi-291cecc/work/reference/console/Console.cpp000066400000000000000000001044321516262404200237020ustar00rootroot00000000000000 #include "windows.h" #include "ruby.h" #ifdef WIN32 #define CONSOLE_EXPORT __declspec(dllexport) #else #error Not compiling on Windows #endif VALUE rb_mWin32; VALUE rb_mConsole; VALUE rb_mAPI; VALUE rb_mConstants; /* old RUBY_METHOD_FUNC() definition doesn't match to prototypes in those days. */ #ifndef ANYARGS #undef RUBY_METHOD_FUNC #define RUBY_METHOD_FUNC(func) ((VALUE (*)())func) #endif #define RB_DEF_S_METHOD(klass,method,func,argtype) \ rb_define_singleton_method(klass,method,RUBY_METHOD_FUNC(func), argtype) #define RB_DEF_API_METHOD(name,argtype) \ RB_DEF_S_METHOD(rb_mAPI,#name,RUBY_METHOD_FUNC(rb_##name), argtype) #define RB_DEF_METHOD(klass,method,func,argtype) \ rb_define_method(klass,method,RUBY_METHOD_FUNC(func), argtype) VALUE rb_getWin32Error() { DWORD e = GetLastError(); LPVOID lpMsgBuf; if (!FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL )) { // Handle the error. return Qnil; } VALUE t = rb_str_new2( (LPCTSTR) lpMsgBuf ); // Free the buffer. LocalFree( lpMsgBuf ); // Raise exception rb_raise(rb_eRuntimeError, RSTRING(t)->ptr); return Qnil; } extern "C" { static VALUE rb_GetStdHandle(VALUE self, VALUE handle) { unsigned long x; if ( FIXNUM_P( handle ) ) { x = NUM2ULONG( handle ); } else { Check_Type( handle, T_BIGNUM ); x = rb_big2ulong(handle); } unsigned long h = PtrToUlong( GetStdHandle( x ) ); return ULONG2NUM(h); } static VALUE rb_AllocConsole(VALUE self) { if (AllocConsole()) return INT2FIX(1); return rb_getWin32Error(); } static VALUE rb_FreeConsole(VALUE self) { if (FreeConsole()) return INT2FIX(1); return rb_getWin32Error(); } static VALUE rb_GenerateConsoleCtrlEvent(VALUE self, VALUE event, VALUE pgid) { unsigned int e = NUM2UINT(event); if ( e != CTRL_C_EVENT && e != CTRL_BREAK_EVENT ) rb_raise(rb_eArgError, "Wrong event: only CTRL_C_EVENT or " "CTRL_BREAK_EVENT accepted."); if ( GenerateConsoleCtrlEvent(e, NUM2UINT(pgid)) ) return INT2FIX(1); return rb_getWin32Error(); } static VALUE rb_GetConsoleMode(VALUE self, VALUE hConsoleOutput) { HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); DWORD mode; if (GetConsoleMode(handle,&mode)) return UINT2NUM(mode); return rb_getWin32Error(); } static VALUE rb_GetConsoleTitle(VALUE self) { char title[1024]; if (GetConsoleTitle((char*)&title,1024)) return rb_str_new2( title ); return rb_getWin32Error(); } static VALUE rb_GetNumberOfConsoleMouseButtons( VALUE self ) { DWORD mb; if (GetNumberOfConsoleMouseButtons( &mb )) return INT2FIX(mb); return rb_getWin32Error(); } static VALUE rb_GetNumberOfConsoleInputEvents( VALUE self, VALUE hConsoleOutput ) { HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); DWORD events; if (GetNumberOfConsoleInputEvents(handle, &events)) return INT2FIX(events); return rb_getWin32Error(); } static VALUE rb_CreateConsoleScreenBuffer( VALUE self, VALUE dwDesiredAccess, VALUE dwShareMode, VALUE dwFlags ) { if (CreateConsoleScreenBuffer( NUM2UINT(dwDesiredAccess), NUM2UINT( dwShareMode), NULL, NUM2UINT( dwFlags), NULL )) return INT2FIX(1); return rb_getWin32Error(); } static VALUE rb_GetConsoleCP( VALUE self ) { unsigned int h = GetConsoleCP(); return UINT2NUM(h); } static VALUE rb_GetConsoleOutputCP( VALUE self ) { unsigned int h = GetConsoleOutputCP(); return UINT2NUM(h); } static VALUE rb_SetConsoleMode( VALUE self, VALUE hConsoleOutput, VALUE Mode ) { HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); if ( SetConsoleMode( handle, NUM2UINT( Mode ) ) ) return INT2FIX(1); return rb_getWin32Error(); } static VALUE rb_SetConsoleCP( VALUE self, VALUE wCodePageID ) { if ( SetConsoleCP( NUM2UINT( wCodePageID ) ) ) return INT2FIX(1); return rb_getWin32Error(); } static VALUE rb_SetConsoleOutputCP( VALUE self, VALUE wCodePageID ) { if ( SetConsoleOutputCP( NUM2UINT( wCodePageID ) ) ) return INT2FIX(1); return rb_getWin32Error(); } static VALUE rb_GetConsoleWindow( VALUE self ) { unsigned long h = PtrToUlong( GetConsoleOutputCP() ); return ULONG2NUM(h); } static VALUE rb_WriteConsole( VALUE self, VALUE hConsoleOutput, VALUE lpBuffer ) { HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); DWORD nNumberOfCharsToWrite = RSTRING(lpBuffer)->len; DWORD lpNumberOfCharsWritten; WriteConsole( handle, RSTRING(lpBuffer)->ptr, nNumberOfCharsToWrite, &lpNumberOfCharsWritten, NULL ); return UINT2NUM( lpNumberOfCharsWritten ); } static VALUE rb_GetLargestConsoleWindowSize( VALUE self, VALUE hConsoleOutput ) { HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); COORD size = GetLargestConsoleWindowSize( handle); VALUE ret = rb_ary_new(); rb_ary_push( ret, UINT2NUM( size.X ) ); rb_ary_push( ret, UINT2NUM( size.Y ) ); return ret; } static VALUE rb_GetConsoleCursorInfo( VALUE self, VALUE hConsoleOutput ) { HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); CONSOLE_CURSOR_INFO out; if ( !GetConsoleCursorInfo( handle, &out ) ) return rb_getWin32Error(); VALUE ret = rb_ary_new(); rb_ary_push( ret, UINT2NUM( out.dwSize ) ); rb_ary_push( ret, UINT2NUM( out.bVisible ) ); return ret; } void rb_ParseEvent(VALUE ret, INPUT_RECORD& event ) { switch(event.EventType) { case KEY_EVENT: { KEY_EVENT_RECORD* kevent=(KEY_EVENT_RECORD *)&(event.Event); rb_ary_push(ret, UINT2NUM(KEY_EVENT)); rb_ary_push(ret, UINT2NUM(kevent->bKeyDown)); rb_ary_push(ret, UINT2NUM(kevent->wRepeatCount)); rb_ary_push(ret, UINT2NUM(kevent->wVirtualKeyCode)); rb_ary_push(ret, UINT2NUM(kevent->wVirtualScanCode)); #ifdef UNICODE rb_ary_push(ret, UINT2NUM(kevent->uChar.UnicodeChar)); #else rb_ary_push(ret, UINT2NUM(kevent->uChar.AsciiChar)); #endif rb_ary_push(ret, UINT2NUM(kevent->dwControlKeyState)); break; } case MOUSE_EVENT: { MOUSE_EVENT_RECORD * mevent=(MOUSE_EVENT_RECORD *)&(event.Event); rb_ary_push(ret, UINT2NUM(MOUSE_EVENT) ); rb_ary_push(ret, UINT2NUM(mevent->dwMousePosition.X) ); rb_ary_push(ret, UINT2NUM(mevent->dwMousePosition.Y) ); rb_ary_push(ret, UINT2NUM(mevent->dwButtonState) ); rb_ary_push(ret, UINT2NUM(mevent->dwControlKeyState) ); rb_ary_push(ret, UINT2NUM(mevent->dwEventFlags) ); break; } case WINDOW_BUFFER_SIZE_EVENT: { WINDOW_BUFFER_SIZE_RECORD* wevent= (WINDOW_BUFFER_SIZE_RECORD *)&(event.Event); rb_ary_push(ret, UINT2NUM(WINDOW_BUFFER_SIZE_EVENT) ); rb_ary_push(ret, UINT2NUM(wevent->dwSize.X) ); rb_ary_push(ret, UINT2NUM(wevent->dwSize.Y) ); } break; case MENU_EVENT: { MENU_EVENT_RECORD* mevent= (MENU_EVENT_RECORD *)&(event.Event); rb_ary_push(ret, UINT2NUM(MENU_EVENT) ); rb_ary_push(ret, UINT2NUM(mevent->dwCommandId) ); } break; case FOCUS_EVENT: { FOCUS_EVENT_RECORD* mevent= (FOCUS_EVENT_RECORD *)&(event.Event); rb_ary_push(ret, UINT2NUM(FOCUS_EVENT) ); rb_ary_push(ret, UINT2NUM(mevent->bSetFocus) ); } break; } } static VALUE rb_PeekConsoleInput( VALUE self, VALUE hConsoleOutput ) { HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); DWORD nofread; INPUT_RECORD event; if (!PeekConsoleInput(handle,&event,1,&nofread)) return rb_getWin32Error(); VALUE ret = rb_ary_new(); rb_ParseEvent( ret, event ); return ret; } static VALUE rb_ReadConsole( VALUE self, VALUE hConsoleOutput, VALUE buffer, VALUE numread ) { HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); DWORD nofread; Check_Type( buffer, T_STRING ); int to_read = NUM2INT(numread); if ( RSTRING(buffer)->len > to_read ) rb_raise(rb_eArgError, "String is too small to read that many characters."); if (ReadConsole(handle,(void *)RSTRING(buffer)->ptr, to_read, &nofread,NULL)) return UINT2NUM(nofread); return rb_getWin32Error(); } static VALUE rb_ReadConsoleInput( VALUE self, VALUE hConsoleOutput ) { HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); DWORD nofread; INPUT_RECORD event; if (!ReadConsoleInput(handle,&event,1,&nofread)) return rb_getWin32Error(); VALUE ret = rb_ary_new(); rb_ParseEvent( ret, event ); return ret; } static VALUE rb_ReadConsoleOutputCharacter( VALUE self, VALUE hConsoleOutput, VALUE charbuf, VALUE len, VALUE x, VALUE y ) { HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); COORD coords; DWORD nofread; coords.X= NUM2UINT( x ); coords.Y= NUM2UINT( y ); int l = NUM2INT(len); if ( RSTRING(charbuf)->len < l*sizeof(TCHAR) ) rb_raise(rb_eArgError, "String is too small to read that many characters."); if (ReadConsoleOutputCharacter(handle,RSTRING(charbuf)->ptr,l, coords,&nofread)) return UINT2NUM( nofread ); return rb_getWin32Error(); } static VALUE rb_ReadConsoleOutputAttribute( VALUE self, VALUE hConsoleOutput, VALUE len, VALUE x, VALUE y ) { HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); COORD coords; DWORD nofread; unsigned short abuffer[80*999*sizeof(unsigned short)]; char cbuffer[80*999]; coords.X= NUM2UINT( x ); coords.Y= NUM2UINT( y ); if (ReadConsoleOutputAttribute(handle, abuffer, NUM2UINT(len), coords,&nofread)) { for(unsigned i=0;ilen < (sizeof(CHAR_INFO)*size.X*size.Y) ) rb_raise(rb_eArgError, "string buffer is too small for reading that many characters."); HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); if (!ReadConsoleOutput(handle,(CHAR_INFO *)RSTRING(buffer)->ptr,size,coords,&from)) return rb_getWin32Error(); VALUE ret = rb_ary_new(); rb_ary_push( ret, INT2FIX(from.Left) ); rb_ary_push( ret, INT2FIX(from.Top) ); rb_ary_push( ret, INT2FIX(from.Right) ); rb_ary_push( ret, INT2FIX(from.Bottom) ); return ret; } static VALUE rb_GetConsoleScreenBufferInfo( VALUE self, VALUE hConsoleOutput ) { HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); CONSOLE_SCREEN_BUFFER_INFO out; if ( !GetConsoleScreenBufferInfo( handle, &out ) ) return rb_getWin32Error(); VALUE ret = rb_ary_new(); rb_ary_push( ret, UINT2NUM( out.dwSize.X ) ); rb_ary_push( ret, UINT2NUM( out.dwSize.Y ) ); rb_ary_push( ret, UINT2NUM( out.dwCursorPosition.X ) ); rb_ary_push( ret, UINT2NUM( out.dwCursorPosition.Y ) ); rb_ary_push( ret, UINT2NUM( out.wAttributes ) ); rb_ary_push( ret, INT2FIX( out.srWindow.Left ) ); rb_ary_push( ret, INT2FIX( out.srWindow.Top ) ); rb_ary_push( ret, INT2FIX( out.srWindow.Right ) ); rb_ary_push( ret, INT2FIX( out.srWindow.Bottom ) ); rb_ary_push( ret, UINT2NUM( out.dwMaximumWindowSize.X ) ); rb_ary_push( ret, UINT2NUM( out.dwMaximumWindowSize.Y ) ); return ret; } #define strEQ(x,y) strcmp(x,y) == 0 DWORD c_constant(char *name) { switch (*name) { case 'A': break; case 'B': if (strEQ(name, "BACKGROUND_BLUE")) #ifdef BACKGROUND_BLUE return BACKGROUND_BLUE; #else goto not_there; #endif if (strEQ(name, "BACKGROUND_GREEN")) #ifdef BACKGROUND_GREEN return BACKGROUND_GREEN; #else goto not_there; #endif if (strEQ(name, "BACKGROUND_INTENSITY")) #ifdef BACKGROUND_INTENSITY return BACKGROUND_INTENSITY; #else goto not_there; #endif if (strEQ(name, "BACKGROUND_RED")) #ifdef BACKGROUND_RED return BACKGROUND_RED; #else goto not_there; #endif break; case 'C': if (strEQ(name, "CAPSLOCK_ON")) #ifdef CAPSLOCK_ON return CAPSLOCK_ON; #else goto not_there; #endif if (strEQ(name, "CONSOLE_TEXTMODE_BUFFER")) #ifdef CONSOLE_TEXTMODE_BUFFER return CONSOLE_TEXTMODE_BUFFER; #else goto not_there; #endif if (strEQ(name, "CTRL_BREAK_EVENT")) #ifdef CTRL_BREAK_EVENT return CTRL_BREAK_EVENT; #else goto not_there; #endif if (strEQ(name, "CTRL_C_EVENT")) #ifdef CTRL_C_EVENT return CTRL_C_EVENT; #else goto not_there; #endif break; case 'D': break; case 'E': if (strEQ(name, "ENABLE_ECHO_INPUT")) #ifdef ENABLE_ECHO_INPUT return ENABLE_ECHO_INPUT; #else goto not_there; #endif if (strEQ(name, "ENABLE_LINE_INPUT")) #ifdef ENABLE_LINE_INPUT return ENABLE_LINE_INPUT; #else goto not_there; #endif if (strEQ(name, "ENABLE_MOUSE_INPUT")) #ifdef ENABLE_MOUSE_INPUT return ENABLE_MOUSE_INPUT; #else goto not_there; #endif if (strEQ(name, "ENABLE_PROCESSED_INPUT")) #ifdef ENABLE_PROCESSED_INPUT return ENABLE_PROCESSED_INPUT; #else goto not_there; #endif if (strEQ(name, "ENABLE_PROCESSED_OUTPUT")) #ifdef ENABLE_PROCESSED_OUTPUT return ENABLE_PROCESSED_OUTPUT; #else goto not_there; #endif if (strEQ(name, "ENABLE_WINDOW_INPUT")) #ifdef ENABLE_WINDOW_INPUT return ENABLE_WINDOW_INPUT; #else goto not_there; #endif if (strEQ(name, "ENABLE_WRAP_AT_EOL_OUTPUT")) #ifdef ENABLE_WRAP_AT_EOL_OUTPUT return ENABLE_WRAP_AT_EOL_OUTPUT; #else goto not_there; #endif if (strEQ(name, "ENHANCED_KEY")) #ifdef ENHANCED_KEY return ENHANCED_KEY; #else goto not_there; #endif break; case 'F': if (strEQ(name, "FILE_SHARE_READ")) #ifdef FILE_SHARE_READ return FILE_SHARE_READ; #else goto not_there; #endif if (strEQ(name, "FILE_SHARE_WRITE")) #ifdef FILE_SHARE_WRITE return FILE_SHARE_WRITE; #else goto not_there; #endif if (strEQ(name, "FOREGROUND_BLUE")) #ifdef FOREGROUND_BLUE return FOREGROUND_BLUE; #else goto not_there; #endif if (strEQ(name, "FOREGROUND_GREEN")) #ifdef FOREGROUND_GREEN return FOREGROUND_GREEN; #else goto not_there; #endif if (strEQ(name, "FOREGROUND_INTENSITY")) #ifdef FOREGROUND_INTENSITY return FOREGROUND_INTENSITY; #else goto not_there; #endif if (strEQ(name, "FOREGROUND_RED")) #ifdef FOREGROUND_RED return FOREGROUND_RED; #else goto not_there; #endif break; case 'G': if (strEQ(name, "GENERIC_READ")) #ifdef GENERIC_READ return GENERIC_READ; #else goto not_there; #endif if (strEQ(name, "GENERIC_WRITE")) #ifdef GENERIC_WRITE return GENERIC_WRITE; #else goto not_there; #endif break; case 'H': break; case 'I': break; case 'J': break; case 'K': if (strEQ(name, "KEY_EVENT")) #ifdef KEY_EVENT return KEY_EVENT; #else goto not_there; #endif break; case 'L': if (strEQ(name, "LEFT_ALT_PRESSED")) #ifdef LEFT_ALT_PRESSED return LEFT_ALT_PRESSED; #else goto not_there; #endif if (strEQ(name, "LEFT_CTRL_PRESSED")) #ifdef LEFT_CTRL_PRESSED return LEFT_CTRL_PRESSED; #else goto not_there; #endif break; case 'M': break; case 'N': if (strEQ(name, "NUMLOCK_ON")) #ifdef NUMLOCK_ON return NUMLOCK_ON; #else goto not_there; #endif break; case 'O': break; case 'P': break; case 'Q': break; case 'R': if (strEQ(name, "RIGHT_ALT_PRESSED")) #ifdef RIGHT_ALT_PRESSED return RIGHT_ALT_PRESSED; #else goto not_there; #endif if (strEQ(name, "RIGHT_CTRL_PRESSED")) #ifdef RIGHT_CTRL_PRESSED return RIGHT_CTRL_PRESSED; #else goto not_there; #endif break; case 'S': if (strEQ(name, "SCROLLLOCK_ON")) #ifdef SCROLLLOCK_ON return SCROLLLOCK_ON; #else goto not_there; #endif if (strEQ(name, "SHIFT_PRESSED")) #ifdef SHIFT_PRESSED return SHIFT_PRESSED; #else goto not_there; #endif if (strEQ(name, "STD_ERROR_HANDLE")) #ifdef STD_ERROR_HANDLE return STD_ERROR_HANDLE; #else goto not_there; #endif if (strEQ(name, "STD_INPUT_HANDLE")) #ifdef STD_INPUT_HANDLE return STD_INPUT_HANDLE; #else goto not_there; #endif if (strEQ(name, "STD_OUTPUT_HANDLE")) #ifdef STD_OUTPUT_HANDLE return STD_OUTPUT_HANDLE; #else goto not_there; #endif break; case 'T': break; case 'U': break; case 'V': break; case 'W': break; case 'X': break; case 'Y': break; case 'Z': break; } rb_raise(rb_eArgError, "Not such constant."); return 0; not_there: rb_raise(rb_eArgError, "Not defined."); return 0; } VALUE rb_constant( VALUE self, VALUE name ) { Check_Type( name, T_STRING ); return ULONG2NUM( c_constant( RSTRING(name)->ptr ) ); } void define_constants() { #define DEF_SELF_CONST(NAME) \ rb_define_const(rb_mConstants, #NAME, ULONG2NUM( (ULONG)NAME ) ); DEF_SELF_CONST( STD_INPUT_HANDLE ); DEF_SELF_CONST( STD_OUTPUT_HANDLE ); DEF_SELF_CONST( STD_ERROR_HANDLE ); DEF_SELF_CONST( INVALID_HANDLE_VALUE ); DEF_SELF_CONST( GENERIC_READ ); DEF_SELF_CONST( GENERIC_WRITE ); DEF_SELF_CONST( FILE_SHARE_READ ); DEF_SELF_CONST( FILE_SHARE_WRITE ); DEF_SELF_CONST( CONSOLE_TEXTMODE_BUFFER ); DEF_SELF_CONST( FOREGROUND_BLUE ); DEF_SELF_CONST( FOREGROUND_GREEN ); DEF_SELF_CONST( FOREGROUND_RED ); DEF_SELF_CONST( FOREGROUND_INTENSITY ); DEF_SELF_CONST( BACKGROUND_BLUE ); DEF_SELF_CONST( BACKGROUND_GREEN ); DEF_SELF_CONST( BACKGROUND_RED ); DEF_SELF_CONST( BACKGROUND_INTENSITY ); DEF_SELF_CONST( ENABLE_PROCESSED_INPUT ); DEF_SELF_CONST( ENABLE_LINE_INPUT ); DEF_SELF_CONST( ENABLE_ECHO_INPUT ); DEF_SELF_CONST( ENABLE_WINDOW_INPUT ); DEF_SELF_CONST( ENABLE_MOUSE_INPUT ); DEF_SELF_CONST( ENABLE_PROCESSED_OUTPUT ); DEF_SELF_CONST( ENABLE_WRAP_AT_EOL_OUTPUT ); DEF_SELF_CONST( KEY_EVENT ); DEF_SELF_CONST( MOUSE_EVENT ); DEF_SELF_CONST( WINDOW_BUFFER_SIZE_EVENT ); DEF_SELF_CONST( MENU_EVENT ); DEF_SELF_CONST( FOCUS_EVENT ); DEF_SELF_CONST( CAPSLOCK_ON ); DEF_SELF_CONST( ENHANCED_KEY ); DEF_SELF_CONST( NUMLOCK_ON ); DEF_SELF_CONST( SHIFT_PRESSED ); DEF_SELF_CONST( LEFT_CTRL_PRESSED ); DEF_SELF_CONST( RIGHT_CTRL_PRESSED ); DEF_SELF_CONST( LEFT_ALT_PRESSED ); DEF_SELF_CONST( RIGHT_ALT_PRESSED ); DEF_SELF_CONST( SCROLLLOCK_ON ); DEF_SELF_CONST( MOUSE_WHEELED ); DEF_SELF_CONST( DOUBLE_CLICK ); DEF_SELF_CONST( MOUSE_MOVED ); DEF_SELF_CONST( FROM_LEFT_1ST_BUTTON_PRESSED ); DEF_SELF_CONST( FROM_LEFT_2ND_BUTTON_PRESSED ); DEF_SELF_CONST( FROM_LEFT_3RD_BUTTON_PRESSED ); DEF_SELF_CONST( FROM_LEFT_4TH_BUTTON_PRESSED ); DEF_SELF_CONST( RIGHTMOST_BUTTON_PRESSED ); DEF_SELF_CONST( CTRL_C_EVENT ); DEF_SELF_CONST( CTRL_BREAK_EVENT ); DEF_SELF_CONST( CTRL_CLOSE_EVENT ); DEF_SELF_CONST( CTRL_LOGOFF_EVENT ); DEF_SELF_CONST( CTRL_SHUTDOWN_EVENT ); } VALUE rb_FillConsoleOutputAttribute( VALUE self, VALUE hConsoleOutput, VALUE wAttribute, VALUE nLength, VALUE col, VALUE row ) { HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); COORD dwWriteCoord; dwWriteCoord.X = NUM2UINT(col); dwWriteCoord.Y = NUM2UINT(row); DWORD numChars; if (FillConsoleOutputAttribute( handle, NUM2UINT(wAttribute), NUM2ULONG(nLength), dwWriteCoord, &numChars )) return ULONG2NUM(numChars); return rb_getWin32Error(); } VALUE rb_SetConsoleScreenBufferSize( VALUE self, VALUE hConsoleOutput, VALUE x, VALUE y ) { HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); COORD size; size.X=NUM2UINT(x); size.Y=NUM2UINT(y); if (SetConsoleScreenBufferSize(handle, size)) return NUM2UINT(1); return rb_getWin32Error(); } VALUE rb_SetConsoleTitle( VALUE self, VALUE title ) { Check_Type( title, T_STRING ); if (SetConsoleTitle(RSTRING( title )->ptr)) return NUM2UINT(1); return rb_getWin32Error(); } VALUE rb_SetStdHandle( VALUE self, VALUE fd, VALUE hConsoleOutput ) { HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); if (SetStdHandle(NUM2UINT(fd), handle)) return NUM2UINT(1); return rb_getWin32Error(); } VALUE rb_SetConsoleWindowInfo( VALUE self, VALUE hConsoleOutput, VALUE bAbsolute, VALUE left, VALUE top, VALUE right, VALUE bottom ) { HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); SMALL_RECT rect; rect.Left = NUM2INT( left ); rect.Top = NUM2INT( top ); rect.Right = NUM2INT( right ); rect.Bottom = NUM2INT( bottom ); if (SetConsoleWindowInfo( handle, NUM2INT( bAbsolute ), &rect )) return UINT2NUM(1); return rb_getWin32Error(); } VALUE rb_SetConsoleCursorPosition( VALUE self, VALUE hConsoleOutput, VALUE col, VALUE row ) { HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); COORD dwWriteCoord; dwWriteCoord.X = NUM2UINT(col); dwWriteCoord.Y = NUM2UINT(row); // Cannot call rb_getWin32Error as this function fails when // setting cursor to last column/row. if ( !SetConsoleCursorPosition( handle, dwWriteCoord ) ) return Qnil; return INT2FIX(1); } VALUE rb_SetConsoleCursorInfo( VALUE self, VALUE hConsoleOutput, VALUE size, VALUE visib ) { HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); CONSOLE_CURSOR_INFO c; c.dwSize = NUM2UINT(size); c.bVisible = NUM2UINT(visib); if ( !SetConsoleCursorInfo( handle, &c ) ) return rb_getWin32Error(); return INT2FIX(1); } VALUE rb_SetConsoleActiveScreenBuffer( VALUE self, VALUE hConsoleOutput ) { HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); if ( !SetConsoleActiveScreenBuffer( handle ) ) return rb_getWin32Error(); return INT2FIX(1); } VALUE rb_SetConsoleTextAttribute( VALUE self, VALUE hConsoleOutput, VALUE wAttributes ) { HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); if ( !SetConsoleTextAttribute( handle, NUM2UINT(wAttributes) ) ) return Qnil; // no getWin32Error to allow piping/redirecting return INT2FIX(1); } VALUE rb_ScrollConsoleScreenBuffer( VALUE self, VALUE hConsoleOutput, VALUE left1, VALUE top1, VALUE right1, VALUE bottom1, VALUE col, VALUE row, VALUE cChar, VALUE attr, VALUE left2, VALUE top2, VALUE right2, VALUE bottom2) { HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); SMALL_RECT scroll, clip; scroll.Left = NUM2INT( left1 ); scroll.Right = NUM2INT( right1 ); scroll.Top = NUM2INT( top1 ); scroll.Bottom = NUM2INT( bottom1 ); clip.Left = NUM2INT( left2 ); clip.Right = NUM2INT( right2 ); clip.Top = NUM2INT( top2 ); clip.Bottom = NUM2INT( bottom2 ); CHAR_INFO fill; #ifdef UNICODE fill.Char.UnicodeChar = NUM2CHR( cChar ); #else fill.Char.AsciiChar = NUM2CHR( cChar ); #endif fill.Attributes = NUM2INT(attr); COORD origin; origin.X = NUM2UINT( col ); origin.Y = NUM2UINT( row ); if ( ScrollConsoleScreenBuffer( handle, &scroll, &clip, origin, &fill ) ) return INT2FIX(1); return rb_getWin32Error(); } VALUE rb_FillConsoleOutputCharacter( VALUE self, VALUE hConsoleOutput, VALUE cCharacter, VALUE nLength, VALUE col, VALUE row ) { HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); COORD dwWriteCoord; dwWriteCoord.X = NUM2UINT(col); dwWriteCoord.Y = NUM2UINT(row); DWORD numChars; if (FillConsoleOutputCharacter( handle, NUM2CHR(cCharacter), NUM2ULONG(nLength), dwWriteCoord, &numChars )) return ULONG2NUM(numChars); return rb_getWin32Error(); } VALUE rb_WriteConsoleInput(int argc, VALUE *argv, VALUE self) { if (argc < 3) rb_raise(rb_eArgError, "Wrong number of arguments."); HANDLE handle = ULongToPtr( NUM2ULONG( argv[0] ) ); WORD type = NUM2INT( argv[1] ); DWORD written; INPUT_RECORD event; event.EventType = type; switch(event.EventType) { case KEY_EVENT: { KEY_EVENT_RECORD* kevent=(KEY_EVENT_RECORD *)&(event.Event); kevent->bKeyDown=(BOOL)NUM2UINT( argv[2] ); kevent->wRepeatCount=NUM2UINT( argv[3] ); kevent->wVirtualKeyCode=NUM2UINT( argv[4] ); kevent->wVirtualScanCode=NUM2UINT( argv[5] ); #ifdef UNICODE if (argc < 7) rb_raise(rb_eArgError, "Wrong number of arguments."); kevent->uChar.UnicodeChar=NUM2UINT( argv[6] ); #else if (argc < 8) rb_raise(rb_eArgError, "Wrong number of arguments."); kevent->uChar.AsciiChar=NUM2UINT( argv[7] ); #endif break; } case MOUSE_EVENT: { if (argc < 7) rb_raise(rb_eArgError, "Wrong number of arguments."); MOUSE_EVENT_RECORD* mevent=(MOUSE_EVENT_RECORD *)&(event.Event); mevent->dwMousePosition.X=NUM2UINT( argv[2] ); mevent->dwMousePosition.Y=NUM2UINT( argv[3] ); mevent->dwButtonState=NUM2UINT( argv[4] ); mevent->dwControlKeyState=NUM2UINT( argv[5] ); mevent->dwEventFlags=NUM2UINT( argv[6] ); break; } case WINDOW_BUFFER_SIZE_EVENT: { if (argc < 4) rb_raise(rb_eArgError, "Wrong number of arguments."); WINDOW_BUFFER_SIZE_RECORD* mevent= (WINDOW_BUFFER_SIZE_RECORD *)&(event.Event); mevent->dwSize.X = NUM2UINT( argv[2] ); mevent->dwSize.Y = NUM2UINT( argv[3] ); } break; case MENU_EVENT: { if (argc < 3) rb_raise(rb_eArgError, "Wrong number of arguments."); MENU_EVENT_RECORD* mevent= (MENU_EVENT_RECORD *)&(event.Event); mevent->dwCommandId = argv[2]; } break; case FOCUS_EVENT: { if (argc < 3) rb_raise(rb_eArgError, "Wrong number of arguments."); FOCUS_EVENT_RECORD* mevent= (FOCUS_EVENT_RECORD *)&(event.Event); mevent->bSetFocus = NUM2UINT( argv[2] ); } default: rb_raise( rb_eArgError, "Unknown type of event."); break; } if (WriteConsoleInput(handle,&event,1,&written)) return INT2FIX(1); return rb_getWin32Error(); } VALUE rb_WriteConsoleOutput(VALUE self, VALUE h, VALUE buffer, VALUE srcwid, VALUE srcht, VALUE startx, VALUE starty, VALUE l, VALUE t, VALUE r, VALUE b) { COORD coords; COORD size; SMALL_RECT to; HANDLE handle = ULongToPtr( NUM2ULONG( h ) ); Check_Type( buffer, T_STRING ); size.X=NUM2UINT( srcwid ); size.Y=NUM2UINT( srcht ); coords.X=NUM2INT( startx ); coords.Y=NUM2INT( starty ); to.Left = NUM2INT( l ); to.Top = NUM2INT( t ); to.Right = NUM2INT( r ); to.Bottom = NUM2INT( b ); if (WriteConsoleOutput(handle,(CHAR_INFO *)RSTRING(buffer)->ptr, size,coords,&to)) { VALUE ret = rb_ary_new(); rb_ary_push( ret, INT2FIX( to.Left ) ); rb_ary_push( ret, INT2FIX( to.Top ) ); rb_ary_push( ret, INT2FIX( to.Right ) ); rb_ary_push( ret, INT2FIX( to.Bottom ) ); return ret; } return rb_getWin32Error(); } VALUE rb_WriteConsoleOutputAttribute(VALUE self, VALUE h, VALUE s, VALUE x, VALUE y) { HANDLE handle = ULongToPtr( NUM2ULONG( h ) ); Check_Type( s, T_STRING ); unsigned short buffer[80*999*sizeof(unsigned short)]; DWORD written; DWORD towrite = RSTRING(s)->len; for(unsigned i=0; iptr[i]); } COORD coords; coords.X=NUM2INT( x ); coords.Y=NUM2INT( y ); if (WriteConsoleOutputAttribute(handle,(const unsigned short *)&buffer, towrite,coords,&written)) { return UINT2NUM( written ); } return rb_getWin32Error(); } VALUE rb_WriteConsoleOutputCharacter(VALUE self, VALUE h, VALUE s, VALUE x, VALUE y) { HANDLE handle = ULongToPtr( NUM2ULONG( h ) ); Check_Type( s, T_STRING ); DWORD written; COORD coords; coords.X=NUM2INT( x ); coords.Y=NUM2INT( y ); if (WriteConsoleOutputCharacter(handle,(LPCTSTR)RSTRING(s)->ptr, RSTRING(s)->len,coords,&written)) { return UINT2NUM( written ); } return rb_getWin32Error(); } CONSOLE_EXPORT void Init_Console(void) { rb_mWin32 = rb_define_module("Win32"); rb_define_const(rb_mKernel, "Win32", rb_mWin32); rb_mConsole = rb_define_class_under(rb_mWin32, "Console", rb_cObject); // Handle Constants rb_mConstants = rb_define_module_under(rb_mConsole,"Constants"); define_constants(); // Handle API rb_mAPI = rb_define_class_under(rb_mConsole, "API", rb_cObject); RB_DEF_API_METHOD(constant, 1); //OK RB_DEF_API_METHOD(AllocConsole, 0); RB_DEF_API_METHOD(CreateConsoleScreenBuffer, 3); //OK RB_DEF_API_METHOD(FillConsoleOutputAttribute, 5); //OK RB_DEF_API_METHOD(FillConsoleOutputCharacter, 5); //OK // RB_DEF_API_METHOD(FillConsoleInputBuffer, 1); // Does not exist anymore RB_DEF_API_METHOD(FreeConsole, 0); RB_DEF_API_METHOD(GenerateConsoleCtrlEvent, 2); RB_DEF_API_METHOD(GetConsoleCP, 0); //OK RB_DEF_API_METHOD(GetConsoleCursorInfo, 1); //OK RB_DEF_API_METHOD(GetConsoleMode, 1); RB_DEF_API_METHOD(GetConsoleOutputCP, 0); RB_DEF_API_METHOD(GetConsoleScreenBufferInfo, 1); //OK RB_DEF_API_METHOD(GetConsoleTitle, 0); RB_DEF_API_METHOD(GetConsoleWindow, 0); RB_DEF_API_METHOD(GetLargestConsoleWindowSize, 1); RB_DEF_API_METHOD(GetNumberOfConsoleInputEvents, 1); RB_DEF_API_METHOD(GetNumberOfConsoleMouseButtons, 0); RB_DEF_API_METHOD(GetStdHandle, 1); //OK RB_DEF_API_METHOD(PeekConsoleInput, 1); //OK RB_DEF_API_METHOD(ReadConsole, 3); //OK RB_DEF_API_METHOD(ReadConsoleInput, 1); //OK RB_DEF_API_METHOD(ReadConsoleOutput, 10); // OK RB_DEF_API_METHOD(ReadConsoleOutputAttribute, 4); // OK RB_DEF_API_METHOD(ReadConsoleOutputCharacter, 5); // OK RB_DEF_API_METHOD(ScrollConsoleScreenBuffer, 13); //OK RB_DEF_API_METHOD(SetConsoleActiveScreenBuffer, 1); RB_DEF_API_METHOD(SetConsoleCP, 1); RB_DEF_API_METHOD(SetConsoleCursorPosition, 3); RB_DEF_API_METHOD(SetConsoleCursorInfo, 3); RB_DEF_API_METHOD(SetConsoleMode, 2); //OK RB_DEF_API_METHOD(SetConsoleOutputCP, 1); RB_DEF_API_METHOD(SetConsoleScreenBufferSize, 3); RB_DEF_API_METHOD(SetConsoleTextAttribute, 2); RB_DEF_API_METHOD(SetConsoleTitle, 1); //OK RB_DEF_API_METHOD(SetConsoleWindowInfo, 6); RB_DEF_API_METHOD(SetStdHandle, 2); RB_DEF_API_METHOD(WriteConsole, 2); RB_DEF_API_METHOD(WriteConsoleInput, -1); RB_DEF_API_METHOD(WriteConsoleOutput, 10); RB_DEF_API_METHOD(WriteConsoleOutputAttribute, 4); RB_DEF_API_METHOD(WriteConsoleOutputCharacter, 4); } } rubyworks-ansi-291cecc/work/reference/console/Console.rdoc000066400000000000000000000512551516262404200240530ustar00rootroot00000000000000# # = NAME # # Win32::Console - Win32 Console and Character Mode Functions # # # = DESCRIPTION # # This module implements the Win32 console and character mode # functions. They give you full control on the console input and output, # including: support of off-screen console buffers (eg. multiple screen # pages) # # - reading and writing of characters, attributes and whole portions of # the screen # # - complete processing of keyboard and mouse events # # - some very funny additional features :) # # # Those functions should also make possible a port of the Unix's curses # library; if there is anyone interested (and/or willing to contribute) # to this project, e-mail me. Thank you. # # # = REFERENCE # # # == Methods # # - Alloc # # Allocates a new console for the process. Returns C on errors, a # nonzero value on success. A process cannot be associated with more # than one console, so this method will fail if there is already an # allocated console. Use Free to detach the process from the console, # and then call Alloc to create a new console. See also: C # # Example: # # Win32::Console::Alloc() # # - Attr [attr] # # Gets or sets the current console attribute. This attribute is used by # the Write method. # # Example: # # attr = console.Attr() # console.Attr(FG_YELLOW | BG_BLUE) # # - Close # # Closes a shortcut object. Note that it is not "strictly" required to # close the objects you created, since the Win32::Shortcut objects are # automatically closed when the program ends (or when you elsehow # destroy such an object). # # Example: # # link.Close() # # - Cls [attr] # # Clear the console, with the specified I if given, or using # ATTR_NORMAL otherwise. # # Example: # # console.Cls() # console.Cls(FG_WHITE | BG_GREEN) # # - Cursor [x, y, size, visible] # # Gets or sets cursor position and appearance. Returns C on # errors, or a 4-element list containing: I, I, I, # I. I and I are the current cursor position; ... # # Example: # # x, y, size, visible = console.Cursor() # # # Get position only # x, y = console.Cursor() # # console.Cursor(40, 13, 50, 1) # # # Set position only # console.Cursor(40, 13) # # # Set size and visibility without affecting position # console.Cursor(-1, -1, 50, 1) # # - Display # # Displays the specified console on the screen. Returns C on errors, # a nonzero value on success. # # Example: # # console.Display() # # - FillAttr [attribute, number, col, row] # # Fills the specified number of consecutive attributes, beginning at # I, I, with the value specified in I. Returns the # number of attributes filled, or C on errors. See also: # C. # # Example: # # console.FillAttr(FG_BLACK | BG_BLACK, 80*25, 0, 0) # # - FillChar char, number, col, row # # Fills the specified number of consecutive characters, beginning at # I, I, with the character specified in I. Returns the # number of characters filled, or C on errors. See also: # C. # # Example: # # console.FillChar("X", 80*25, 0, 0) # # - Flush # # Flushes the console input buffer. All the events in the buffer are # discarded. Returns C on errors, a nonzero value on success. # # Example: # # console.Flush() # # - Free # # Detaches the process from the console. Returns C on errors, a # nonzero value on success. See also: C. # # Example: # # Win32::Console::Free() # # - GenerateCtrlEvent [type, processgroup] # # Sends a break signal of the specified I to the specified # I. I can be one of the following constants: # # CTRL_BREAK_EVENT # CTRL_C_EVENT # # they signal, respectively, the pressing of Control + Break and of # Control + C; if not specified, it defaults to CTRL_C_EVENT. # I is the pid of a process sharing the same console. If # omitted, it defaults to 0 (the current process), which is also the # only meaningful value that you can pass to this function. Returns # C on errors, a nonzero value on success. # # Example: # # # break this script now # Win32::Console::GenerateCtrlEvent() # # - GetEvents # # Returns the number of unread input events in the console's input # buffer, or C on errors. See also: C, C, # C, C. # # Example: # # events = console.GetEvents() # # - Info # # Returns an array of informations about the console (or C on # errors), which contains: # # * columns (X size) of the console buffer. # # * rows (Y size) of the console buffer. # # * current column (X position) of the cursor. # # * current row (Y position) of the cursor. # # * current attribute used for C. # # * left column (X of the starting point) of the current console window. # # * top row (Y of the starting point) of the current console window. # # * right column (X of the final point) of the current console window. # # * bottom row (Y of the final point) of the current console window. # # * maximum number of columns for the console window, given the current # buffer size, font and the screen size. # # * maximum number of rows for the console window, given the current # buffer size, font and the screen size. # # # See also: Attr, Cursor, Size, Window, MaxWindow. # # Example: # # info = console.Info() # puts "Cursor at #{info[3]}, #{info[4]}." # # - Input # # Reads an event from the input buffer. Returns an array of values, which # depending on the event's nature are: # # - keyboard event # # The array will contain: # # * event type: 1 for keyboard # # * key down: TRUE if the key is being pressed, FALSE if the key is being released # # * repeat count: the number of times the key is being held down # # * virtual keycode: the virtual key code of the key # # * virtual scancode: the virtual scan code of the key # # * char: the ASCII code of the character (if the key is a character key, 0 otherwise) # # * control key state: the state of the control keys (SHIFTs, CTRLs, ALTs, etc.) # # # - mouse event # # The array will contain: # # * event type: 2 for mouse # # * mouse pos. X: X coordinate (column) of the mouse location # # * mouse pos. Y: Y coordinate (row) of the mouse location # # * button state: the mouse button(s) which are pressed # # * control key state: the state of the control keys (SHIFTs, CTRLs, ALTs, etc.) # # * event flags: the type of the mouse event # # # This method will return nil on errors. Note that the events # returned are depending on the input Mode of the console; for example, # mouse events are not intercepted unless ENABLE_MOUSE_INPUT is # specified. See also: GetEvents, InputChar, Mode, # PeekInput, WriteInput. # # Example: # # event = console.Input() # # - InputChar number # # Reads and returns I characters from the console input buffer, # or nil on errors. See also: Input, Mode. # # Example: # # key = console.InputChar(1) # # - InputCP [codepage] # # Gets or sets the input code page used by the console. Note that this # doesn't apply to a console object, but to the standard input # console. This attribute is used by the Write method. See also: # OutputCP. # # Example: # # codepage = Win32::Console::InputCP() # Win32::Console::InputCP(437) # # - MaxWindow # # Returns the size of the largest possible console window, based on the # current font and the size of the display. The result is nil on # errors, otherwise a 2-element list containing col, row. # # Example: # # maxCol, maxRow = console.MaxWindow() # # - Mode [flags] # # Gets or sets the input or output mode of a console. I can be a # combination of the following constants: # # ENABLE_LINE_INPUT # ENABLE_ECHO_INPUT # ENABLE_PROCESSED_INPUT # ENABLE_WINDOW_INPUT # ENABLE_MOUSE_INPUT # ENABLE_PROCESSED_OUTPUT # ENABLE_WRAP_AT_EOL_OUTPUT # # For more informations on the meaning of those flags, please refer to # the L<"Microsoft's Documentation">. # # Example: # # mode = console.Mode() # console.Mode(ENABLE_MOUSE_INPUT | ENABLE_PROCESSED_INPUT) # # - MouseButtons # # Returns the number of the buttons on your mouse, or nil on errors. # # Example: # # puts "Your mouse has #{Win32::Console::MouseButtons()} buttons." # # - Win32::Console.new standard_handle # # - Win32::Console.new [accessmode, sharemode] # # Creates a new console object. The first form creates a handle to a # standard channel, I can be one of the following: # # STD_OUTPUT_HANDLE # STD_ERROR_HANDLE # STD_INPUT_HANDLE # # The second form, instead, creates a console screen buffer in memory, # which you can access for reading and writing as a normal console, and # then redirect on the standard output (the screen) with Display. In # this case, you can specify one or both of the following values for # I: # # GENERIC_READ # GENERIC_WRITE # # which are the permissions you will have on the created buffer, and one # or both of the following values for I: # # FILE_SHARE_READ # FILE_SHARE_WRITE # # which affect the way the console can be shared. If you don't specify # any of those parameters, all 4 flags will be used. # # Example: # # stdout = Win32::Console.new(STD_OUTPUT_HANDLE) # stderr = Win32::Console.new(STD_ERROR_HANDLE) # stdin = Win32::Console.new(STD_INPUT_HANDLE) # # buffer = Win32::Console.new() # buffer = Win32::Console.new(GENERIC_READ | GENERIC_WRITE) # # - OutputCP [codepage] # # Gets or sets the output code page used by the console. Note that this # doesn't apply to a console object, but to the standard output console. # See also: InputCP. # # Example: # # codepage = Win32::Console::OutputCP() # Win32::Console::OutputCP(437) # # - PeekInput # # Does exactly the same as Input, except that the event read is not # removed from the input buffer. See also: GetEvents, Input, # InputChar, Mode, WriteInput. # # Example: # # event = console.PeekInput() # # - ReadAttr [number, col, row] # # Reads the specified I of consecutive attributes, beginning at # I, I, from the console. Returns the attributes read (a # variable containing one character for each attribute), or nil on # errors. You can then pass the returned variable to WriteAttr to # restore the saved attributes on screen. See also: ReadChar, # ReadRect. # # Example: # # colors = console.ReadAttr(80*25, 0, 0) # # - ReadChar [number, col, row] # # Reads the specified I of consecutive characters, beginning at # I, I, from the console. Returns a string containing the # characters read, or nil on errors. You can then pass the # returned variable to WriteChar to restore the saved characters on # screen. See also: ReadAttr, ReadRect. # # Example: # # chars = console.ReadChar(80*25, 0, 0) # # - ReadRect left, top, right, bottom # # Reads the content (characters and attributes) of the rectangle # specified by I, I, I, I from the console. # Returns a string containing the rectangle read, or nil on errors. # You can then pass the returned variable to WriteRect to restore the # saved rectangle on screen (or on another console). See also: # ReadAttr, ReadChar. # # Example: # # rect = console.ReadRect(0, 0, 80, 25) # # - Scroll left, top, right, bottom, col, row, char, attr, # [cleft, ctop, cright, cbottom] # # Moves a block of data in a console buffer the block is identified by # I, I, I, I, while I, I identify # the new location of the block. The cells left empty as a result of # the move are filled with the character I and attribute I. # Optionally you can specify a clipping region with I, I, # I, I, so that the content of the console outside this # rectangle are unchanged. Returns nil on errors, a nonzero value # on success. # # Example: # # # scrolls the screen 10 lines down, filling with black spaces # console.Scroll(0, 0, 80, 25, 0, 10, " ", FG_BLACK | BG_BLACK) # # - Select standard_handle # # Redirects a standard handle to the specified console. # I can have one of the following values: # # STD_INPUT_HANDLE # STD_OUTPUT_HANDLE # STD_ERROR_HANDLE # # Returns nil on errors, a nonzero value on success. # # Example: # # console.Select(STD_OUTPUT_HANDLE) # # - Size [col, row] # # Gets or sets the console buffer size. # # Example: # # x, y = console.Size() # console.Size(80, 25) # # - Title [title] # # Gets or sets the title bar the string of the current console window. # # Example: # # title = console.Title() # console.Title("This is a title") # # - Window [flag, left, top, right, bottom] # # Gets or sets the current console window size. If called without # arguments, returns a 4-element list containing the current window # coordinates in the form of I, I, I, I. To # set the window size, you have to specify an additional I # parameter: if it is 0 (zero), coordinates are considered relative to # the current coordinates; if it is non-zero, coordinates are absolute. # # Example: # # left, top, right, bottom = console.Window() # console.Window(1, 0, 0, 80, 50) # # - Write string # # Writes I on the console, using the current attribute, that you # can set with Attr, and advancing the cursor as needed. This isn't # so different from Perl's "print" statement. Returns the number of # characters written or nil on errors. See also: WriteAttr, # WriteChar, WriteRect. # # Example: # # console.Write("Hello, world!") # # - WriteAttr attrs, col, row # # Writes the attributes in the string I, beginning at I, # I, without affecting the characters that are on screen. The # string attrs can be the result of a ReadAttr function, or you can # build your own attribute string; in this case, keep in mind that every # attribute is treated as a character, not a number (see example). # Returns the number of attributes written or nil on errors. See # also: Write, WriteChar, WriteRect. # # Example: # # console.WriteAttr($attrs, 0, 0) # # # note the use of chr()... # attrs = (FG_BLACK | BG_WHITE).chr() * 80 # console.WriteAttr(attrs, 0, 0) # # - WriteChar chars, col, row # # Writes the characters in the string attr, beginning at col, row, # without affecting the attributes that are on screen. The string chars # can be the result of a ReadChar function, or a normal string. Returns # the number of characters written or nil on errors. See also: # Write, WriteAttr, WriteRect. # # Example: # # console.WriteChar("Hello, worlds!", 0, 0) # # - WriteInput (event) # # Pushes data in the console input buffer. I<(event)> is a list of values, # for more information see Input. The string chars can be the result of # a ReadChar function, or a normal string. Returns the number of # characters written or nil on errors. See also: Write, # WriteAttr, WriteRect. # # Example: # # console.WriteInput(event) # # - WriteRect rect, left, top, right, bottom # # Writes a rectangle of characters and attributes (contained in rect) # on the console at the coordinates specified by left, top, # right, bottom. rect can be the result of a ReadRect # function. Returns nil on errors, otherwise a 4-element list # containing the coordinates of the affected rectangle, in the format # left, top, right, bottom. See also: Write, # WriteAttr, WriteChar. # # Example: # # console.WriteRect(rect, 0, 0, 80, 25) # # # == Constants # # The following constants are defined in the namespace of # Win32::Console::Constants and are brought into the current # namespace when the module is required: # # BACKGROUND_BLUE # BACKGROUND_GREEN # BACKGROUND_INTENSITY # BACKGROUND_RED # CAPSLOCK_ON # CONSOLE_TEXTMODE_BUFFER # ENABLE_ECHO_INPUT # ENABLE_LINE_INPUT # ENABLE_MOUSE_INPUT # ENABLE_PROCESSED_INPUT # ENABLE_PROCESSED_OUTPUT # ENABLE_WINDOW_INPUT # ENABLE_WRAP_AT_EOL_OUTPUT # ENHANCED_KEY # FILE_SHARE_READ # FILE_SHARE_WRITE # FOREGROUND_BLUE # FOREGROUND_GREEN # FOREGROUND_INTENSITY # FOREGROUND_RED # LEFT_ALT_PRESSED # LEFT_CTRL_PRESSED # NUMLOCK_ON # GENERIC_READ # GENERIC_WRITE # RIGHT_ALT_PRESSED # RIGHT_CTRL_PRESSED # SCROLLLOCK_ON # SHIFT_PRESSED # STD_INPUT_HANDLE # STD_OUTPUT_HANDLE # STD_ERROR_HANDLE # # Additionally, these other constants are also added to your current # namespace when requiring the module: # # FG_BLACK # FG_BLUE # FG_LIGHTBLUE # FG_RED # FG_LIGHTRED # FG_GREEN # FG_LIGHTGREEN # FG_MAGENTA # FG_LIGHTMAGENTA # FG_CYAN # FG_LIGHTCYAN # FG_BROWN # FG_YELLOW # FG_GRAY # FG_WHITE # # BG_BLACK # BG_BLUE # BG_LIGHTBLUE # BG_RED # BG_LIGHTRED # BG_GREEN # BG_LIGHTGREEN # BG_MAGENTA # BG_LIGHTMAGENTA # BG_CYAN # BG_LIGHTCYAN # BG_BROWN # BG_YELLOW # BG_GRAY # BG_WHITE # # ATTR_NORMAL # ATTR_INVERSE # # ATTR_NORMAL is set to gray foreground on black background (DOS's # standard colors). # # # == Microsoft's Documentation # # Documentation for the Win32 Console and Character mode Functions can # be found on Microsoft's site at this URL: # # http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/sys/src/conchar.htm # # A reference of the available functions is at: # # http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/sys/src/conchar_34.htm # # # = VERSION HISTORY # # * 0.031 (24 Sep 1999) # # * Fixed typo in GenerateCtrlEvent(). # # * Converted and added pod documentation (from Jan Dubois ). # # * 0.03 (07 Apr 1997) # # * Added "GenerateCtrlEvent" method. # # * The PLL file now comes in 2 versions, one for Perl version 5.001 # (build 110) and one for Perl version 5.003 (build 300 and higher, # EXCEPT 304). # # * added an installation program that will automatically copy the right # version in the right place. # # * 0.01 (09 Feb 1997) # # * First public release. # # = AUTHORS # # Aldo Calpini Perl module # # Gonzalo Garramuo Ruby Port # # = CREDITS # # Thanks to: Jesse Dougherty, Dave Roth, ActiveWare, and the # Perl-Win32-Users community. # # # = DISCLAIMER # # This program is FREE; you can redistribute, modify, disassemble, or # even reverse engineer this software at your will. Keep in mind, # however, that NOTHING IS GUARANTEED to work and everything you do is # AT YOUR OWN RISK - I will not take responsibility for any damage, loss # of money and/or health that may arise from the use of this program! # # This is distributed under the terms of Larry Wall's Artistic License. # rubyworks-ansi-291cecc/work/reference/console/Console_ANSI.rdoc000066400000000000000000000240031516262404200246540ustar00rootroot00000000000000# # = NAME # # Win32::Console::ANSI - Ruby extension to emulate ANSI console on Win32 system. # # = SYNOPSIS # # require "Win32::Console::ANSI" # # puts "\e[1;34mThis text is bold blue.\e[0m" # puts "This text is normal."" # puts "\e[33;45;1mBold yellow on magenta.\e[0m" # puts "This text is normal." # # With the Term::ANSIColor module one increases the readability: # # require "Win32::Console::ANSI" # require "Term::ANSIColor" # # puts color 'bold blue' # puts "This text is bold blue." # puts color 'reset' # puts "This text is normal." # puts colored ("Bold yellow on magenta.", 'bold yellow on_magenta') # puts "This text is normal." # # And even more with Term::ANSIScreen: # # require "Win32::Console::ANSI; # require "Term::ANSIScreen qw/:color :cursor :screen/; # # locate 1, 1; puts "@ This is (1,1)", savepos; # puts locate(24,60), "@ This is (24,60)"; loadpos; # puts down(2), clline, "@ This is (3,16)"; # setscroll 1, 20; # color 'black on white'; clline; # puts "This line is black on white."; # puts color 'reset'; puts "This text is normal."; # puts colored ("This text is bold blue.", 'bold blue'); # puts "This text is normal."; # puts colored ['bold blue'], "This text is bold blue."; # puts "This text is normal."; # # = DESCRIPTION # # Windows NT/2000/XP does not support ANSI escape sequences in Win32 Console # applications. This module emulates an ANSI console for the script which # uses it. # # # == Escape sequences for Cursor Movement # # * \e[#A # # CUU: CUrsor Up: Moves the cursor up by the specified number of lines without # changing columns. If the cursor is already on the top line, this sequence # is ignored. \e[A is equivalent to \e[1A. # # * \e[#B # # CUD: CUrsor Down: Moves the cursor down by the specified number of lines # without changing columns. If the cursor is already on the bottom line, # this sequence is ignored. \e[B is equivalent to \e[1B. # # * \e[#C # # CUF: CUrsor Forward: Moves the cursor forward by the specified number of # columns without changing lines. If the cursor is already in the # rightmost column, this sequence is ignored. \e[C is equivalent to \e[1C. # # * \e[#D # # CUB: CUrsor Backward: Moves the cursor back by the specified number of # columns without changing lines. If the cursor is already in the leftmost # column, this sequence is ignored. \e[D is equivalent to \e[1D. # # * \e[#E # # CNL: Cursor Next Line: Moves the cursor down the indicated # of rows, to # column 1. \e[E is equivalent to \e[1E. # # * \e[#F # # CPL: Cursor Preceding Line: Moves the cursor up the indicated # of rows, # to column 1. \e[F is equivalent to \e[1F. # # * \e[#G # # CHA: Cursor Horizontal Absolute: Moves the cursor to indicated column in # current row. \e[G is equivalent to \e[1G. # # * \e[#;#H # # CUP: CUrsor Position: Moves the cursor to the specified position. The first # # specifies the line number, the second # specifies the column. # If you do not specify a position, the cursor moves to the # home position: the upper-left corner of the screen (line 1, column 1). # # * \e[#;#f # # HVP: Horizontal and Vertical Position. # Works the same way as the preceding escape sequence. # # * \e[s # # SCP: Save Cursor Position: Saves the current cursor position. You can move # the cursor to the saved cursor position by using the Restore Cursor # Position sequence. # # * \e[u # # RCP: Restore Cursor Position: Returns the cursor to the position stored # by the Save Cursor Position sequence. # # == Escape sequences for Display Edition # # * \e[#J # # ED: Erase Display: # # * \e[0J # # Clears the screen from cursor to end of display. The cursor position is unchanged. # # * \e[1J # # Clears the screen from start to cursor. The cursor position is unchanged. # # * \e[2J # # Clears the screen and moves the cursor to the home position (line 1, column 1). # # \e[J is equivalent to \e[0J. (Some terminal/emulators respond to \e[J as if # it were \e[2J. Here, the default is 0; it's the norm) # # * \e[#K # # EL: Erase Line: # # * \e[0K # # Clears all characters from the cursor position to the end of the line # (including the character at the cursor position). # The cursor position is unchanged. # # * \e[1K # # Clears all characters from start of line to the cursor position. # (including the character at the cursor position). # The cursor position is unchanged. # # * \e[2K # # Clears all characters of the whole line. # The cursor position is unchanged. # # \e[K is equivalent to \e[0K. # # * \e[#L # # IL: Insert Lines: The cursor line and all lines below it move down # lines, # leaving blank space. The cursor position is unchanged. The bottommost # # lines are lost. \e[L is equivalent to \e[1L. # # * \e[#M # # DL: Delete Line: The block of # lines at and below the cursor are deleted; # all lines below them move up # lines to fill in the gap, leaving # blank # lines at the bottom of the screen. The cursor position is unchanged. # \e[M is equivalent to \e[1M. # # * \e#\@ # # ICH: Insert CHaracter: The cursor character and all characters to the right # of it move right # columns, leaving behind blank space. # The cursor position is unchanged. The rightmost # characters on the line are lost. # # * \e[#P # # DCH: Delete CHaracter: The block of # characters at and to the right of the # cursor are deleted; all characters to the right of it move left # columns, # leaving behind blank space. The cursor position is unchanged. # \e[P is equivalent to \e[1P. # # # == Escape sequences for Set Graphics Rendition # # * \e[#;...;#m # # SGM: Set Graphics Mode: Calls the graphics functions specified by the # following values. These specified functions remain active until the next # occurrence of this escape sequence. Graphics mode changes the colors and # attributes of text (such as bold and underline) displayed on the # screen. # # * Text attributes # # 0 All attributes off # 1 Bold on # 4 Underscore on # 7 Reverse video on # 8 Concealed on # # 21 Bold off # 24 Underscore off # 27 Reverse video off # 28 Concealed off # # * Foreground colors # # 30 Black # 31 Red # 32 Green # 33 Yellow # 34 Blue # 35 Magenta # 36 Cyan # 37 White # # * Background colors # # 40 Black # 41 Red # 42 Green # 43 Yellow # 44 Blue # 45 Magenta # 46 Cyan # 47 White # # \e[m is equivalent to \e0m. # # == Escape sequences for Select Character Set # # * \e(U # # Select null mapping - straight to character from the codepage of the console. # # * \e(K # # Select Windows to DOS mapping, if the corresponding map exist; no effect # otherwise. This is the default mapping (if the map exist, of course). It's # useful becarequire "one types the script with a Windows-based editor (using a # Windows codepage) and the script prints its messages on the console using # another codepage: without translation, the characters with a code greatest # than 127 are different and the printed messages may be not readable. # # The conversion is done by the module Encode if it is installed (it's a # standard module with Perl5.8, not Ruby yet). Otherwise, the conversion is limited to the # following couples: # # WinLatin1 (cp1252) to DOSLatin1 (cp850) # WinLatin1 (cp1252) to DOSLatinUS (cp437) # WinLatin2 (cp1250) to DOSLatin2 (cp852) # WinCyrillic(cp1251) to DOSCyrillic (cp855) # # * \e(#X # # This escape sequence is I standard! It's an experimental one, just for # fun :-) # # If and only if the console uses an Unicode police, it is possible to # change its codepage with this escape sequence. No effect with an ordinary # "Raster Font". (For Windows NT/2000/XP the currently available Unicode # console font is the Lucida Console TrueType font.) # # is the number of the codepage needed, 855 for cp855 for instance. # # # = LIMITATIONS # # * Due to DOS-console limitations, the blink mode (text attributes 5 and 25) is not implemented. # # = SEE ALSO # # Win32::Console, Term::ANSIColor, Term::ANSIScreen. # # = AUTHOR # # J-L Morel jl_morel@bribes.org # # Home page: http://www.bribes.org/perl/wANSIConsole.html # # Gonzalo Garramuo GGarramuno@aol.com Ruby port # # = CREDITS # # Render unto Csar the things which are Csar's... # # This module requires the module Win32::Console. Thanks to Aldo Calpini. # # The method used to overload the print function is due to Matt Sergeant # (see his module Win32::ASP). # # = COPYRIGHT # # Copyright (c) 2004 Gonzalo Garramuo. All rights reserved. # Copyright (c) 2003 J-L Morel. All rights reserved. # # This program is free software; you can redistribute it and/or modify it under # the terms of the Artistic License. # # rubyworks-ansi-291cecc/work/reference/console/HISTORY.txt000066400000000000000000000005601516262404200234730ustar00rootroot00000000000000v1.0 - Added .dup to _printString function to avoid mangling outside string references. Removed the other (later) .dup call. Turned of some exceptions that were conflicting with using the module with pipes or redirections. v0.8 - Fixed bugs in reading routines, added ruby docs, and sample test suite. v0.5 - First public release. rubyworks-ansi-291cecc/work/reference/console/INSTALL.txt000066400000000000000000000006231516262404200234400ustar00rootroot00000000000000 To compile and install: Open a windows console. > vcvars32.bat # to set up microsoft's compiling environment # this is located in the bin/ directory of the MSVC compiler > ruby extconf.rb # to create a Makefile > nmake # to compile > nmake install # to install To test: > cd test > dir # to see available samples > ruby [anysample] rubyworks-ansi-291cecc/work/reference/console/Makefile000066400000000000000000000105461516262404200232360ustar00rootroot00000000000000 SHELL = /bin/sh #### Start of system configuration section. #### srcdir = C:/ruby/visualc/Console topdir = $(rubylibdir)/$(arch) hdrdir = $(rubylibdir)/$(arch) VPATH = $(srcdir) DESTDIR = c: prefix = $(DESTDIR)/ruby exec_prefix = $(prefix) bindir = $(exec_prefix)/bin sitelibdir = $(sitedir)/$(ruby_version) datadir = $(prefix)/share sitedir = $(prefix)/lib/ruby/site_ruby sharedstatedir = $(DESTDIR)/etc archdir = $(rubylibdir)/$(arch) localstatedir = $(DESTDIR)/var infodir = $(prefix)/info oldincludedir = $(DESTDIR)/usr/include libexecdir = $(exec_prefix)/libexec compile_dir = $(DESTDIR)/WINDOWS/Escritorio/Programacion/ruby/win32 sbindir = $(exec_prefix)/sbin includedir = $(prefix)/include sysconfdir = $(prefix)/etc sitearchdir = $(sitelibdir)/$(sitearch) mandir = $(prefix)/man libdir = $(exec_prefix)/lib rubylibdir = $(libdir)/ruby/$(ruby_version) CC = cl -nologo LIBRUBY = $(RUBY_SO_NAME).lib LIBRUBY_A = $(RUBY_SO_NAME)-static.lib LIBRUBYARG_SHARED = $(LIBRUBY) LIBRUBYARG_STATIC = $(LIBRUBY_A) CFLAGS = -MD -Zi -O2b2xg- -G6 CPPFLAGS = -I. -I$(topdir) -I$(hdrdir) -I$(srcdir) -I. -I./.. -I./../missing CXXFLAGS = $(CFLAGS) DLDFLAGS = -link -incremental:no -debug -opt:ref -opt:icf -dll $(LIBPATH) -def:$(DEFFILE) LDSHARED = cl -nologo -LD AR = lib -nologo EXEEXT = .exe RUBY_INSTALL_NAME = ruby RUBY_SO_NAME = msvcrt-ruby18 arch = i386-mswin32 sitearch = i386-msvcrt ruby_version = 1.8 RUBY = ruby RM = $(RUBY) -run -e rm -- -f MAKEDIRS = $(RUBY) -run -e mkdir -- -p INSTALL_PROG = $(RUBY) -run -e install -- -vpm 0755 INSTALL_DATA = $(RUBY) -run -e install -- -vpm 0644 #### End of system configuration section. #### LIBPATH = -libpath:"$(libdir)" DEFFILE = $(TARGET)-$(arch).def CLEANFILES = DISTCLEANFILES = $(DEFFILE) target_prefix = LOCAL_LIBS = LIBS = $(LIBRUBYARG_SHARED) oldnames.lib user32.lib advapi32.lib wsock32.lib OBJS = Console.obj TARGET = Console DLLIB = $(TARGET).so STATIC_LIB = $(TARGET).lib RUBYCOMMONDIR = $(sitedir)$(target_prefix) RUBYLIBDIR = $(sitelibdir)$(target_prefix) RUBYARCHDIR = $(sitearchdir)$(target_prefix) CLEANLIBS = "$(TARGET).{lib,exp,il?,tds,map}" $(DLLIB) CLEANOBJS = "*.{obj,lib,s[ol],pdb,bak}" all: $(DLLIB) static: $(STATIC_LIB) clean: @$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) distclean: clean @$(RM) Makefile extconf.h conftest.* mkmf.log @$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) realclean: distclean install: $(RUBYARCHDIR) install: $(RUBYARCHDIR)/$(DLLIB) $(RUBYARCHDIR)/$(DLLIB): $(DLLIB) $(RUBYARCHDIR) @$(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR) install: $(RUBYLIBDIR)/Win32 install: $(RUBYLIBDIR)/Win32/Console.rb $(RUBYLIBDIR)/Win32/Console.rb: $(srcdir)/lib/Win32/Console.rb $(RUBYLIBDIR)/Win32 @$(INSTALL_DATA) $(srcdir)/lib/Win32/Console.rb $(RUBYLIBDIR)/Win32 install: $(RUBYLIBDIR)/Win32/Console install: $(RUBYLIBDIR)/Win32/Console/ANSI.rb $(RUBYLIBDIR)/Win32/Console/ANSI.rb: $(srcdir)/lib/Win32/Console/ANSI.rb $(RUBYLIBDIR)/Win32/Console @$(INSTALL_DATA) $(srcdir)/lib/Win32/Console/ANSI.rb $(RUBYLIBDIR)/Win32/Console install: $(RUBYLIBDIR)/Term install: $(RUBYLIBDIR)/Term/ansicolor.rb $(RUBYLIBDIR)/Term/ansicolor.rb: $(srcdir)/lib/Term/ansicolor.rb $(RUBYLIBDIR)/Term @$(INSTALL_DATA) $(srcdir)/lib/Term/ansicolor.rb $(RUBYLIBDIR)/Term $(RUBYARCHDIR): @$(MAKEDIRS) $(RUBYARCHDIR) $(RUBYLIBDIR)/Win32: @$(MAKEDIRS) $(RUBYLIBDIR)/Win32 $(RUBYLIBDIR)/Win32/Console: @$(MAKEDIRS) $(RUBYLIBDIR)/Win32/Console $(RUBYLIBDIR)/Term: @$(MAKEDIRS) $(RUBYLIBDIR)/Term site-install: install .SUFFIXES: .c .cc .m .cxx .cpp .C .obj {$(srcdir)}.cc{}.obj: $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/) .cc.obj: $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/) {$(srcdir)}.cpp{}.obj: $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/) .cpp.obj: $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/) {$(srcdir)}.cxx{}.obj: $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/) .cxx.obj: $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/) {$(srcdir)}.C{}.obj: $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/) .C.obj: $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/) {$(srcdir)}.c{}.obj: $(CC) $(CFLAGS) $(CPPFLAGS) -c -Tc$(<:\=/) .c.obj: $(CC) $(CFLAGS) $(CPPFLAGS) -c -Tc$(<:\=/) $(DLLIB): $(OBJS) $(DEFFILE) @-$(RM) $@ @-$(RM) $(TARGET).lib $(LDSHARED) -Fe$(@) $(OBJS) $(LIBS) $(LOCAL_LIBS) $(DLDFLAGS) $(STATIC_LIB): $(OBJS) $(AR) -machine:x86 -out:$@ $(OBJS) $(DEFFILE): $(RUBY) -e "puts 'EXPORTS', 'Init_$(TARGET)'" > $@ rubyworks-ansi-291cecc/work/reference/console/README.txt000066400000000000000000000021451516262404200232700ustar00rootroot00000000000000 This file implements a port of Perl's Win32::Console and Win32::Console::ANSI modules. Win32::Console allows controling the windows command line terminal thru an OO-interface. This allows you to query the terminal (find its size, characters, attributes, etc). The interface and functionality should be identical to Perl's. Win32::Console consists of a Ruby .rb interface. For best performance, this library has been also ported to C. If you lack a C compiler, you can still use the class thru the ruby interface. If you can compile it, then the ruby interface is not used and the C functions are called instead. Win32::Console::ANSI is a class derived from IO that seamlessly translates ANSI Esc control character codes into Windows' command.exe or cmd.exe equivalents. These modules allow you to develop command-line tools that can take advantage of the unix terminal functions while still being portable. One of the most common uses for this is to allow to color your output. The modules are disted with Term/ansicolor.rb, too, as it is a nice thing to verify it is working properly. rubyworks-ansi-291cecc/work/reference/console/extconf.rb000066400000000000000000000007431516262404200235670ustar00rootroot00000000000000################################################################# # # To compile and install, do this: # # Make sure your compiling environment is in your path. # In the case of MSVC, this involves running vcvars32.bat first # which is located in the bin directory of MS Visual C++. # # Then: # # > ruby extconf.rb # > nmake Makefile # > nmake install # # ################################################################## require 'mkmf' create_makefile('Console') rubyworks-ansi-291cecc/work/reference/console/lib/000077500000000000000000000000001516262404200223365ustar00rootroot00000000000000rubyworks-ansi-291cecc/work/reference/console/lib/Term/000077500000000000000000000000001516262404200232455ustar00rootroot00000000000000rubyworks-ansi-291cecc/work/reference/console/lib/Term/ansicolor.rb000066400000000000000000000033051516262404200255640ustar00rootroot00000000000000module Term module ANSIColor @@attributes = [ [ :clear , 0 ], [ :reset , 0 ], # synonym for :clear [ :bold , 1 ], [ :dark , 2 ], [ :italic , 3 ], # not widely implemented [ :underline , 4 ], [ :underscore , 4 ], # synonym for :underline [ :blink , 5 ], [ :rapid_blink , 6 ], # not widely implemented [ :negative , 7 ], # no reverse because of String#reverse [ :concealed , 8 ], [ :strikethrough, 9 ], # not widely implemented [ :black , 30 ], [ :red , 31 ], [ :green , 32 ], [ :yellow , 33 ], [ :blue , 34 ], [ :magenta , 35 ], [ :cyan , 36 ], [ :white , 37 ], [ :on_black , 40 ], [ :on_red , 41 ], [ :on_green , 42 ], [ :on_yellow , 43 ], [ :on_blue , 44 ], [ :on_magenta , 45 ], [ :on_cyan , 46 ], [ :on_white , 47 ], ] @@attributes.each do |c, v| eval %Q{ def #{c.to_s}(string = nil) result = "\e[#{v}m" if block_given? result << yield result << "\e[0m" elsif string result << string result << "\e[0m" elsif respond_to?(:to_str) result << self result << "\e[0m" end return result end } end ColoredRegexp = /\e\[([34][0-7]|[0-9])m/ def uncolored(string = nil) if block_given? yield.gsub(ColoredRegexp, '') elsif string string.gsub(ColoredRegexp, '') elsif respond_to?(:to_str) gsub(ColoredRegexp, '') else '' end end def attributes @@attributes.map { |c| c[0] } end module_function :attributes end end # vim: set cin sw=4 ts=4: rubyworks-ansi-291cecc/work/reference/console/lib/Win32/000077500000000000000000000000001516262404200232405ustar00rootroot00000000000000rubyworks-ansi-291cecc/work/reference/console/lib/Win32/Console.rb000066400000000000000000000776741516262404200252140ustar00rootroot00000000000000# Win32::Console: an object implementing the Win32 API Console functions # Copyright (C) 2003 Gonzalo Garramuno (ggarramuno@aol.com) # # Original Win32API_Console was: # Copyright (C) 2001 Michael L. Semon (mlsemon@sega.net) begin # If Console.so is available, use that. Otherwise, we define # equivalent functions in ruby (a tad slower) # That dll should define everything in an identical interface # to all the ruby code that the rescue below defines. require "Console.so" STDERR.print "Using faster, DLL Console.so\n" if $DEBUG rescue Exception STDERR.print "Using slower, non-DLL Console.rb\n" if $DEBUG module Win32 class Console end end # The WINDOWS constants module Win32::Console::Constants STD_INPUT_HANDLE = 0xFFFFFFF6 STD_OUTPUT_HANDLE = 0xFFFFFFF5 STD_ERROR_HANDLE = 0xFFFFFFF4 INVALID_HANDLE_VALUE = 0xFFFFFFFF GENERIC_READ = 0x80000000 GENERIC_WRITE = 0x40000000 FILE_SHARE_READ = 0x00000001 FILE_SHARE_WRITE = 0x00000002 CONSOLE_TEXTMODE_BUFFER = 0x00000001 FOREGROUND_BLUE = 0x0001 FOREGROUND_GREEN = 0x0002 FOREGROUND_RED = 0x0004 FOREGROUND_INTENSITY = 0x0008 BACKGROUND_BLUE = 0x0010 BACKGROUND_GREEN = 0x0020 BACKGROUND_RED = 0x0040 BACKGROUND_INTENSITY = 0x0080 ENABLE_PROCESSED_INPUT = 0x0001 ENABLE_LINE_INPUT = 0x0002 ENABLE_ECHO_INPUT = 0x0004 ENABLE_WINDOW_INPUT = 0x0008 ENABLE_MOUSE_INPUT = 0x0010 ENABLE_PROCESSED_OUTPUT = 0x0001 ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002 KEY_EVENT = 0x0001 MOUSE_EVENT = 0x0002 WINDOW_BUFFER_SIZE_EVENT = 0x0004 MENU_EVENT = 0x0008 FOCUS_EVENT = 0x0010 CAPSLOCK_ON = 0x0080 ENHANCED_KEY = 0x0100 NUMLOCK_ON = 0x0020 SHIFT_PRESSED = 0x0010 LEFT_CTRL_PRESSED = 0x0008 RIGHT_CTRL_PRESSED = 0x0004 LEFT_ALT_PRESSED = 0x0002 RIGHT_ALT_PRESSED = 0x0001 SCROLLLOCK_ON = 0x0040 MOUSE_WHEELED = 0x0004 DOUBLE_CLICK = 0x0002 MOUSE_MOVED = 0x0001 FROM_LEFT_1ST_BUTTON_PRESSED = 0x0001 FROM_LEFT_2ND_BUTTON_PRESSED = 0x0004 FROM_LEFT_3RD_BUTTON_PRESSED = 0x0008 FROM_LEFT_4TH_BUTTON_PRESSED = 0x0010 RIGHTMOST_BUTTON_PRESSED = 0x0002 CTRL_C_EVENT = 0x0000 CTRL_BREAK_EVENT = 0x0001 CTRL_CLOSE_EVENT = 0x0002 CTRL_LOGOFF_EVENT = 0x0005 CTRL_SHUTDOWN_EVENT = 0x0006 end # The actual api to access windows functions class Win32::Console::API require 'Win32API' private # This is a class-wide cache that will hold Win32API objects. As each # Win32API object is about 920 bytes, I didn't want to initialize all of # them at one time. That would waste about 42 kB for this object because # it has 47 functions. However, to not have a cache at all would reduce # the speed of this object by 164%. @@m_AllocConsole = nil @@m_CreateConsoleScreenBuffer = nil @@m_FillConsoleOutputAttribute = nil @@m_FillConsoleOutputCharacter = nil @@m_FlushConsoleInputBuffer = nil @@m_FreeConsole = nil @@m_GenerateConsoleCtrlEvent = nil @@m_GetConsoleCP = nil @@m_GetConsoleCursorInfo = nil @@m_GetConsoleMode = nil @@m_GetConsoleOutputCP = nil @@m_GetConsoleScreenBufferInfo = nil @@m_GetConsoleTitle = nil @@m_GetConsoleWindow = nil @@m_GetLargestConsoleWindowSize = nil @@m_GetNumberOfConsoleInputEvents = nil @@m_GetNumberOfConsoleMouseButtons = nil @@m_GetStdHandle = nil @@m_PeekConsoleInput = nil @@m_ReadConsole = nil @@m_ReadConsoleInput = nil @@m_ReadConsoleOutput = nil @@m_ReadConsoleOutputAttribute = nil @@m_ReadConsoleOutputCharacter = nil @@m_ScrollConsoleScreenBuffer = nil @@m_SetConsoleActiveScreenBuffer = nil @@m_SetConsoleCP = nil @@m_SetConsoleCursorInfo = nil @@m_SetConsoleCursorPosition = nil @@m_SetConsoleMode = nil @@m_SetConsoleOutputCP = nil @@m_SetConsoleScreenBufferSize = nil @@m_SetConsoleTextAttribute = nil @@m_SetConsoleTitle = nil @@m_SetConsoleWindowInfo = nil @@m_SetStdHandle = nil @@m_WriteConsole = nil @@m_WriteConsoleInput = nil @@m_WriteConsoleOutput = nil @@m_WriteConsoleOutputAttribute = nil @@m_WriteConsoleOutputCharacter = nil public class << self def constant(t) begin eval "return Win32::Console::Constants::#{t}" rescue return nil end end def AllocConsole() if @@m_AllocConsole == nil @@m_AllocConsole = Win32API.new( "kernel32", "AllocConsole", [], 'l' ) end @@m_AllocConsole.call() end def CreateConsoleScreenBuffer( dwDesiredAccess, dwShareMode, dwFlags ) if @@m_CreateConsoleScreenBuffer == nil @@m_CreateConsoleScreenBuffer = Win32API.new( "kernel32", "CreateConsoleScreenBuffer", ['l', 'l', 'p', 'l', 'p'], 'l' ) end @@m_CreateConsoleScreenBuffer.call( dwDesiredAccess, dwShareMode, nil, dwFlags, nil ) end def FillConsoleOutputAttribute( hConsoleOutput, wAttribute, nLength, col, row ) if @@m_FillConsoleOutputAttribute == nil @@m_FillConsoleOutputAttribute = Win32API.new( "kernel32", "FillConsoleOutputAttribute", ['l', 'i', 'l', 'l', 'p'], 'l' ) end dwWriteCoord = (row << 16) + col lpNumberOfAttrsWritten = ' ' * 4 @@m_FillConsoleOutputAttribute.call( hConsoleOutput, wAttribute, nLength, dwWriteCoord, lpNumberOfAttrsWritten ) return lpNumberOfAttrsWritten.unpack('L') end def FillConsoleOutputCharacter( hConsoleOutput, cCharacter, nLength, col, row ) if @@m_FillConsoleOutputCharacter == nil @@m_FillConsoleOutputCharacter = Win32API.new( "kernel32", "FillConsoleOutputCharacter", ['l', 'i', 'l', 'l', 'p'], 'l' ) end dwWriteCoord = (row << 16) + col lpNumberOfAttrsWritten = ' ' * 4 @@m_FillConsoleOutputCharacter.call( hConsoleOutput, cCharacter, nLength, dwWriteCoord, lpNumberOfAttrsWritten ) return lpNumberOfAttrsWritten.unpack('L') end def FlushConsoleInputBuffer( hConsoleInput ) if @@m_FlushConsoleInputBuffer == nil @@m_FlushConsoleInputBuffer = Win32API.new( "kernel32", "FillConsoleInputBuffer", ['l'], 'l' ) end @@m_FlushConsoleInputBuffer.call( hConsoleInput ) end def FreeConsole() if @@m_FreeConsole == nil @@m_FreeConsole = Win32API.new( "kernel32", "FreeConsole", [], 'l' ) end @@m_FreeConsole.call() end def GenerateConsoleCtrlEvent( dwCtrlEvent, dwProcessGroupId ) if @@m_GenerateConsoleCtrlEvent == nil @@m_GenerateConsoleCtrlEvent = Win32API.new( "kernel32", "GenerateConsoleCtrlEvent", ['l', 'l'], 'l' ) end @@m_GenerateConsoleCtrlEvent.call( dwCtrlEvent, dwProcessGroupId ) end def GetConsoleCP() if @@m_GetConsoleCP == nil @@m_GetConsoleCP = Win32API.new( "kernel32", "GetConsoleCP", [], 'l' ) end @@m_GetConsoleCP.call() end def GetConsoleCursorInfo( hConsoleOutput ) if @@m_GetConsoleCursorInfo == nil @@m_GetConsoleCursorInfo = Win32API.new( "kernel32", "GetConsoleCursorInfo", ['l', 'p'], 'l' ) end lpConsoleCursorInfo = ' ' * 8 @@m_GetConsoleCursorInfo.call( hConsoleOutput, lpConsoleCursorInfo ) return lpConsoleCursorInfo.unpack('LL') end def GetConsoleMode( hConsoleHandle ) if @@m_GetConsoleMode == nil @@m_GetConsoleMode = Win32API.new( "kernel32", "GetConsoleMode", ['l', 'p'], 'l' ) end lpMode = ' ' * 4 @@m_GetConsoleMode.call( hConsoleHandle, lpMode ) return lpMode.unpack('L') end def GetConsoleOutputCP() if @@m_GetConsoleOutputCP == nil @@m_GetConsoleOutputCP = Win32API.new( "kernel32", "GetConsoleOutputCP", [], 'l' ) end @@m_GetConsoleOutputCP.call() end def GetConsoleScreenBufferInfo( hConsoleOutput ) if @@m_GetConsoleScreenBufferInfo == nil @@m_GetConsoleScreenBufferInfo = Win32API.new( "kernel32", "GetConsoleScreenBufferInfo", ['l', 'p'], 'l' ) end lpBuffer = ' ' * 22 @@m_GetConsoleScreenBufferInfo.call( hConsoleOutput, lpBuffer ) return lpBuffer.unpack('SSSSSssssSS') end def GetConsoleTitle() if @@m_GetConsoleTitle == nil @@m_GetConsoleTitle = Win32API.new( "kernel32", "GetConsoleTitle", ['p', 'l'], 'l' ) end nSize = 120 lpConsoleTitle = ' ' * nSize @@m_GetConsoleTitle.call( lpConsoleTitle, nSize ) return lpConsoleTitle.strip end def GetConsoleWindow() if @@m_GetConsoleWindow == nil @@m_GetConsoleWindow = Win32API.new( "kernel32", "GetConsoleWindow", [], 'l' ) end @@m_GetConsoleWindow.call() end def GetLargestConsoleWindowSize( hConsoleOutput ) if @@m_GetLargestConsoleWindowSize == nil @@m_GetLargestConsoleWindowSize = Win32API.new( "kernel32", "GetLargestConsoleWindowSize", ['l'], 'l' ) end coord = @@m_GetLargestConsoleWindowSize.call( hConsoleOutput ) x = coord >> 16 y = coord & 0x0000ffff return [x,y] end def GetNumberOfConsoleInputEvents( hConsoleInput ) if @@m_GetNumberOfConsoleInputEvents == nil @@m_GetNumberOfConsoleInputEvents = Win32API.new( "kernel32", "GetNumberOfConsoleInputEvents", ['l', 'p'], 'l' ) end lpcNumberOfEvents = 0 @@m_GetNumberOfConsoleInputEvents.call( hConsoleInput, lpcNumberOfEvents ) return lpcNumberOfEvents end def GetNumberOfConsoleMouseButtons( ) if @@m_GetNumberOfConsoleMouseButtons == nil @@m_GetNumberOfConsoleMouseButtons = Win32API.new( "kernel32", "GetNumberOfConsoleMouseButtons", ['p'], 'l' ) end lpNumberOfMouseButtons = 0 @@m_GetNumberOfConsoleMouseButtons.call( lpNumberOfMouseButtons ) return lpNumberOfMouseButtons end def GetStdHandle( nStdHandle ) if @@m_GetStdHandle == nil @@m_GetStdHandle = Win32API.new( "kernel32", "GetStdHandle", ['l'], 'l' ) end @@m_GetStdHandle.call( nStdHandle ) end # <> : This is not an actual API function, just a concept description in the SDK. def PeekConsoleInput( hConsoleInput ) if @@m_PeekConsoleInput == nil @@m_PeekConsoleInput = Win32API.new( "kernel32", "PeekConsoleInput", ['l', 'p', 'l', 'p'], 'l' ) end lpNumberOfEventsRead = ' ' * 4 lpBuffer = ' ' * 20 nLength = 20 @@m_PeekConsoleInput.call( hConsoleInput, lpBuffer, nLength, lpNumberOfEventsRead ) type = lpBuffer.unpack('s')[0] case type when KEY_EVENT return lpBuffer.unpack('sSSSSCS') when MOUSE_EVENT return lpBuffer.unpack('sSSSS') when WINDOW_BUFFER_SIZE_EVENT return lpBuffer.unpack('sS') when MENU_EVENT return lpBuffer.unpack('sS') when FOCUS_EVENT return lpBuffer.unpack('sS') else return [] end end def ReadConsole( hConsoleInput, lpBuffer, nNumberOfCharsToRead ) if @@m_ReadConsole == nil @@m_ReadConsole = Win32API.new( "kernel32", "ReadConsole", ['l', 'p', 'l', 'p', 'p'], 'l' ) end lpBuffer = ' ' * nNumberOfCharsToRead unless lpBuffer lpNumberOfCharsRead = ' ' * 4 lpReserved = ' ' * 4 @@m_ReadConsole.call( hConsoleInput, lpBuffer, nNumberOfCharsToRead, lpNumberOfCharsRead, lpReserved ) return lpNumberOfCharsRead.unpack('L') end def ReadConsoleInput( hConsoleInput ) if @@m_ReadConsoleInput == nil @@m_ReadConsoleInput = Win32API.new( "kernel32", "ReadConsoleInput", ['l', 'p', 'l', 'p'], 'l' ) end lpNumberOfEventsRead = ' ' * 4 lpBuffer = ' ' * 20 nLength = 20 @@m_ReadConsoleInput.call( hConsoleInput, lpBuffer, nLength, lpNumberOfEventsRead ) type = lpBuffer.unpack('s')[0] case type when KEY_EVENT return lpBuffer.unpack('sSSSSCS') when MOUSE_EVENT return lpBuffer.unpack('sSSSS') when WINDOW_BUFFER_SIZE_EVENT return lpBuffer.unpack('sS') when MENU_EVENT return lpBuffer.unpack('sS') when FOCUS_EVENT return lpBuffer.unpack('sS') else return [] end end def ReadConsoleOutput( hConsoleOutput, lpBuffer, cols, rows, bufx, bufy, left, top, right, bottom ) if @@m_ReadConsoleOutput == nil @@m_ReadConsoleOutput = Win32API.new( "kernel32", "ReadConsoleOutput", ['l', 'p', 'l', 'l', 'p'], 'l' ) end dwBufferSize = cols * rows * 4 lpBuffer = ' ' * dwBufferSize dwBufferCoord = (bufy << 16) + bufx lpReadRegion = [ left, top, right, bottom ].pack('ssss') @@m_ReadConsoleOutput.call( hConsoleOutput, lpBuffer, dwBufferSize, dwBufferCoord, lpReadRegion ) end def ReadConsoleOutputAttribute( hConsoleOutput, nLength, col, row ) if @@m_ReadConsoleOutputAttribute == nil @@m_ReadConsoleOutputAttribute = Win32API.new( "kernel32", "ReadConsoleOutputAttribute", ['l', 'p', 'l', 'l', 'p'], 'l' ) end lpAttribute = ' ' * nLength dwReadCoord = (row << 16) + col lpNumberOfAttrsRead = ' ' * 4 @@m_ReadConsoleOutputAttribute.call( hConsoleOutput, lpAttribute, nLength, dwReadCoord, lpNumberOfAttrsRead ) return lpAttribute end def ReadConsoleOutputCharacter( hConsoleOutput, lpCharacter, nLength, col, row ) if @@m_ReadConsoleOutputCharacter == nil @@m_ReadConsoleOutputCharacter = Win32API.new( "kernel32", "ReadConsoleOutputCharacter", ['l', 'p', 'l', 'l', 'p'], 'l' ) end dwReadCoord = (row << 16) + col lpNumberOfCharsRead = ' ' * 4 @@m_ReadConsoleOutputCharacter.call( hConsoleOutput, lpCharacter, nLength, dwReadCoord, lpNumberOfCharsRead ) return lpNumberOfCharsRead.unpack('L') end def ScrollConsoleScreenBuffer( hConsoleOutput, left1, top1, right1, bottom1, col, row, char, attr, left2, top2, right2, bottom2 ) if @@m_ScrollConsoleScreenBuffer == nil @@m_ScrollConsoleScreenBuffer = Win32API.new( "kernel32", "ScrollConsoleScreenBuffer", ['l', 'p', 'p', 'l', 'p'], 'l' ) end lpScrollRectangle = [left1, top1, right1, bottom1].pack('ssss') lpClipRectangle = [left2, top2, right2, bottom2].pack('ssss') dwDestinationOrigin = (row << 16) + col lpFill = [char, attr].pack('ss') @@m_ScrollConsoleScreenBuffer.call( hConsoleOutput, lpScrollRectangle, lpClipRectangle, dwDestinationOrigin, lpFill ) end def SetConsoleActiveScreenBuffer( hConsoleOutput ) if @@m_SetConsoleActiveScreenBuffer == nil @@m_SetConsoleActiveScreenBuffer = Win32API.new( "kernel32", "SetConsoleActiveScreenBuffer", ['l'], 'l' ) end @@m_SetConsoleActiveScreenBuffer.call( hConsoleOutput ) end # <>: Will probably not be implemented. def SetConsoleCP( wCodePageID ) if @@m_SetConsoleCP == nil @@m_SetConsoleCP = Win32API.new( "kernel32", "SetConsoleCP", ['l'], 'l' ) end @@m_SetConsoleCP.call( wCodePageID ) end def SetConsoleCursorInfo( hConsoleOutput, col, row ) if @@m_SetConsoleCursorInfo == nil @@m_SetConsoleCursorInfo = Win32API.new( "kernel32", "SetConsoleCursorInfo", ['l', 'p'], 'l' ) end lpConsoleCursorInfo = [size,visi].pack('LL') @@m_SetConsoleCursorInfo.call( hConsoleOutput, lpConsoleCursorInfo ) end def SetConsoleCursorPosition( hConsoleOutput, col, row ) if @@m_SetConsoleCursorPosition == nil @@m_SetConsoleCursorPosition = Win32API.new( "kernel32", "SetConsoleCursorPosition", ['l', 'p'], 'l' ) end dwCursorPosition = (row << 16) + col @@m_SetConsoleCursorPosition.call( hConsoleOutput, dwCursorPosition ) end def SetConsoleMode( hConsoleHandle, lpMode ) if @@m_SetConsoleMode == nil @@m_SetConsoleMode = Win32API.new( "kernel32", "SetConsoleMode", ['l', 'p'], 'l' ) end @@m_SetConsoleMode.call( hConsoleHandle, lpMode ) end def SetConsoleOutputCP( wCodePageID ) if @@m_SetConsoleOutputCP == nil @@m_SetConsoleOutputCP = Win32API.new( "kernel32", "GetConsoleOutputCP", ['l'], 'l' ) end @@m_SetConsoleOutputCP.call( wCodePageID ) end def SetConsoleScreenBufferSize( hConsoleOutput, col, row ) if @@m_SetConsoleScreenBufferSize == nil @@m_SetConsoleScreenBufferSize = Win32API.new( "kernel32", "SetConsoleScreenBufferSize", ['l', 'l'], 'l' ) end dwSize = (row << 16) + col @@m_SetConsoleScreenBufferSize.call( hConsoleOutput, dwSize ) end def SetConsoleTextAttribute( hConsoleOutput, wAttributes ) if @@m_SetConsoleTextAttribute == nil @@m_SetConsoleTextAttribute = Win32API.new( "kernel32", "SetConsoleTextAttribute", ['l', 'i'], 'l' ) end @@m_SetConsoleTextAttribute.call( hConsoleOutput, wAttributes ) end def SetConsoleTitle( lpConsoleTitle ) if @@m_SetConsoleTitle == nil @@m_SetConsoleTitle = Win32API.new( "kernel32", "SetConsoleTitle", ['p'], 'l' ) end @@m_SetConsoleTitle.call( lpConsoleTitle ) end def SetConsoleWindowInfo( hConsoleOutput, bAbsolute, left, top, right, bottom ) if @@m_SetConsoleWindowInfo == nil @@m_SetConsoleWindowInfo = Win32API.new( "kernel32", "SetConsoleWindowInfo", ['l', 'l', 'p'], 'l' ) end lpConsoleWindow = [ left, top, right, bottom ].pack('ssss') @@m_SetConsoleWindowInfo.call( hConsoleOutput, bAbsolute, lpConsoleWindow ) end def SetStdHandle( nStdHandle, hHandle ) if @@m_SetStdHandle == nil @@m_SetStdHandle = Win32API.new( "kernel32", "SetStdHandle", ['l', 'l'], 'l' ) end @@m_SetStdHandle.call( nStdHandle, hHandle ) end def WriteConsole( hConsoleOutput, lpBuffer ) if @@m_WriteConsole == nil @@m_WriteConsole = Win32API.new( "kernel32", "WriteConsole", ['l', 'p', 'l', 'p', 'p'], 'l' ) end nNumberOfCharsToWrite = lpBuffer.length() lpNumberOfCharsWritten = ' ' * 4 lpReserved = ' ' * 4 @@m_WriteConsole.call( hConsoleOutput, lpBuffer, nNumberOfCharsToWrite, lpNumberOfCharsWritten, lpReserved ) return lpNumberOfCharsWritten end def WriteConsoleInput( hConsoleInput, lpBuffer ) if @@m_WriteConsoleInput == nil @@m_WriteConsoleInput = Win32API.new( "kernel32", "WriteConsoleInput", ['l', 'p', 'l', 'p'], 'l' ) end @@m_WriteConsoleInput.call( hConsoleInput, lpBuffer, nLength, lpNumberOfEventsWritten ) end # @@ Todo: Test this def WriteConsoleOutput( hConsoleOutput, buffer, cols, rows, bufx, bufy, left, top, right, bottom ) if @@m_WriteConsoleOutput == nil @@m_WriteConsoleOutput = Win32API.new( "kernel32", "WriteConsoleOutput", ['l', 'p', 'l', 'l', 'p'], 'l' ) end lpBuffer = buffer.flatten.pack('ss' * buffer.length() * 2) dwBufferSize = (buffer.length() << 16) + 2 dwBufferCoord = (row << 16) + col lpWriteRegion = [ left, top, right, bottom ].pack('ssss') @@m_WriteConsoleOutput.call( hConsoleOutput, lpBuffer, dwBufferSize, dwBufferCoord, lpWriteRegion ) end def WriteConsoleOutputAttribute( hConsoleOutput, lpAttribute, col, row ) if @@m_WriteConsoleOutputAttribute == nil @@m_WriteConsoleOutputAttribute = Win32API.new( "kernel32", "WriteConsoleOutputAttribute", ['l', 'p', 'l', 'l', 'p'], 'l' ) end nLength = lpAttribute.length() dwWriteCoord = (row << 16) + col lpNumberOfAttrsWritten = ' ' * 4 @@m_WriteConsoleOutputAttribute.call( hConsoleOutput, lpAttribute, nLength, dwWriteCoord, lpNumberOfAttrsWritten ) return lpNumberOfAttrsWritten.unpack('L') end def WriteConsoleOutputCharacter( hConsoleOutput, lpCharacter, col, row ) if @@m_WriteConsoleOutputCharacter == nil @@m_WriteConsoleOutputCharacter = Win32API.new( "kernel32", "WriteConsoleOutputCharacter", ['l', 'p', 'l', 'l', 'p'], 'l' ) end nLength = lpCharacter.length() dwWriteCoord = (row << 16) + col lpNumberOfCharsWritten = ' ' * 4 @@m_WriteConsoleOutputCharacter.call( hConsoleOutput, lpCharacter, nLength, dwWriteCoord, lpNumberOfCharsWritten ) return lpNumberOfCharsWritten.unpack('L') end end end end # rescue module Win32 class Console VERSION = '1.0' include Win32::Console::Constants def initialize( t = nil ) if t and ( t == STD_INPUT_HANDLE or t == STD_OUTPUT_HANDLE or t == STD_ERROR_HANDLE ) @handle = API.GetStdHandle( t ) else param1 = GENERIC_READ | GENERIC_WRITE param2 = FILE_SHARE_READ | FILE_SHARE_WRITE @handle = API.CreateConsoleScreenBuffer( param1, param2, CONSOLE_TEXTMODE_BUFFER ) end end def Display return API.SetConsoleActiveScreenBuffer(@handle) end def Select(type) return API.SetStdHandle(type,@handle) end def Title(title = nil) if title return API.SetConsoleTitle(title) else return API.GetConsoleTitle() end end def WriteChar(s, col, row) API.WriteConsoleOutputCharacter( @handle, s, col, row ) end def ReadChar(size, col, row) buffer = ' ' * size if API.ReadConsoleOutputCharacter( @handle, buffer, size, col, row ) return buffer else return nil end end def WriteAttr(attr, col, row) API.WriteConsoleOutputAttribute( @handle, attr, col, row ) end def ReadAttr(size, col, row) x = API.ReadConsoleOutputAttribute( @handle, size, col, row ) return x.unpack('c'*size) end def Cursor(*t) col, row, size, visi = t if col row = -1 if !row if col < 0 or row < 0 curr_col, curr_row = API.GetConsoleScreenBufferInfo(@handle) col = curr_col if col < 0 row = curr_row if row < 0 end API.SetConsoleCursorPosition( @handle, col, row ) if size and visi curr_size, curr_visi = API.GetConsoleCursorInfo( @handle ) size = curr_size if size < 0 visi = curr_visi if visi < 0 size = 1 if size < 1 size = 99 if size > 99 API.SetConsoleCursorInfo( @handle, size, visi ) end else d, d, curr_col, curr_row = API.GetConsoleScreenBufferInfo(@handle) curr_size, curr_visi = API.GetConsoleCursorInfo( @handle ) return [ curr_col, curr_row, curr_size, curr_visi ] end end def Write(s) API.WriteConsole( @handle, s ) end def ReadRect( left, top, right, bottom ) col = right - left + 1 row = bottom - top + 1 size = col * row buffer = ' ' * size * 4 if API.ReadConsoleOutput( @handle, buffer, col, row, 0, 0, left, top, right, bottom ) #return buffer.unpack('US'*size) # for unicode return buffer.unpack('axS'*size) # for ascii else return nil end end def WriteRect( buffer, left, top, right, bottom ) col = right - left + 1 row = bottom - top + 1 API.WriteConsoleOutput( @handle, buffer, col, row, 0, 0, left, top, right, bottom ) end def Scroll( left1, top1, right1, bottom1, col, row, char, attr, left2, top2, right2, bottom2 ) API.ScrollConsoleScreenBuffer(@handle, left1, top1, right1, bottom1, col, row, char, attr, left2, top2, right2, bottom2) end def MaxWindow(flag = nil) if !flag info = API.GetConsoleScreenBufferInfo(@handle) return info[9], info[10] else return API.GetLargestConsoleWindowSize(@handle) end end def Info() return API.GetConsoleScreenBufferInfo( @handle ) end def GetEvents() return API.GetNumberOfConsoleInputEvents(@handle) end def Flush() return API.FlushConsoleInputBuffer(@handle) end def InputChar(number = nil) number = 1 unless number buffer = ' ' * number if API.ReadConsole(@handle, buffer, number) == number return buffer else return nil end end def Input() API.ReadConsoleInput(@handle) end def PeekInput() API.PeekConsoleInput(@handle) end def Mode(mode = nil) if mode mode = mode.pack('L') if mode === Array API.SetConsoleMode(@handle, mode) else return API.GetConsoleMode(@handle) end end def WriteInput(*t) API.WriteConsoleInput(@handle, *t) end def Attr(*attr) if attr.size > 0 API.SetConsoleTextAttribute( @handle, attr[0] ) else info = API.GetConsoleScreenBufferInfo( @handle ) return info[4] end end def Size(*t) if t.size == 0 col, row = API.GetConsoleScreenBufferInfo(@handle ) return [col, row] else row = -1 if !t[1] col = -1 if !t[0] if col < 0 or row < 0 curr_col, curr_row = Size() col = curr_col if col < 0 row = curr_row if row < 0 end API.SetConsoleScreenBufferSize(@handle, row, col) end end def Window(*t) if t.size != 5 info = API.GetConsoleScreenBufferInfo( @handle ) return info[5..8] else API.SetConsoleWindowInfo(@handle, t[0], t[1], t[2], t[3], t[4]) end end def FillAttr(attr, number = 1, col = -1, row = -1) if col < 0 or row < 0 d, d, curr_col, curr_row = API.GetConsoleScreenBufferInfo(@handle) col = curr_col if col < 0 row = curr_row if row < 0 end API.FillConsoleOutputAttribute(@handle, attr, number, col, row) end def FillChar(char, number, col = -1, row = -1) if col < 0 or row < 0 d, d, curr_col, curr_row = API.GetConsoleScreenBufferInfo(@handle) col = curr_col if col < 0 row = curr_row if row < 0 end API.FillConsoleOutputCharacter(@handle, char[0], number, col, row) end def Cls() attr = ATTR_NORMAL x, y = Size() left, top, right , bottom = Window() vx = right - left vy = bottom - top FillChar(' ', x*y, 0, 0) FillAttr(attr, x*y, 0, 0) Cursor(0,0) Window(1,0,0,vx,vy) end def Console.Free() API.FreeConsole() end def Console.Alloc() API.AllocConsole() end def Console.MouseButtons() API.GetNumberOfConsoleMouseButtons() end def Console.InputCP(codepage=nil) if codepage API.SetConsoleCP(codepage) else return API.GetConsoleCP() end end def Console.OutputCP(codepage=nil) if codepage API.SetConsoleOutputCP(codepage) else return API.GetConsoleOutputCP() end end def Console.GenerateCtrlEvent( type=nil, pid=nil ) type = API.constant('CTRL_C_EVENT') if type == nil pid = 0 if pid == nil API.GenerateConsoleCtrlEvent(type, pid) end end end FG_BLACK = 0 FG_BLUE = Win32::Console::API.constant("FOREGROUND_BLUE") FG_LIGHTBLUE = Win32::Console::API.constant("FOREGROUND_BLUE")| Win32::Console::API.constant("FOREGROUND_INTENSITY") FG_RED = Win32::Console::API.constant("FOREGROUND_RED") FG_LIGHTRED = Win32::Console::API.constant("FOREGROUND_RED")| Win32::Console::API.constant("FOREGROUND_INTENSITY") FG_GREEN = Win32::Console::API.constant("FOREGROUND_GREEN") FG_LIGHTGREEN = Win32::Console::API.constant("FOREGROUND_GREEN")| Win32::Console::API.constant("FOREGROUND_INTENSITY") FG_MAGENTA = Win32::Console::API.constant("FOREGROUND_RED")| Win32::Console::API.constant("FOREGROUND_BLUE") FG_LIGHTMAGENTA = Win32::Console::API.constant("FOREGROUND_RED")| Win32::Console::API.constant("FOREGROUND_BLUE")| Win32::Console::API.constant("FOREGROUND_INTENSITY") FG_CYAN = Win32::Console::API.constant("FOREGROUND_GREEN")| Win32::Console::API.constant("FOREGROUND_BLUE") FG_LIGHTCYAN = Win32::Console::API.constant("FOREGROUND_GREEN")| Win32::Console::API.constant("FOREGROUND_BLUE")| Win32::Console::API.constant("FOREGROUND_INTENSITY") FG_BROWN = Win32::Console::API.constant("FOREGROUND_RED")| Win32::Console::API.constant("FOREGROUND_GREEN") FG_YELLOW = Win32::Console::API.constant("FOREGROUND_RED")| Win32::Console::API.constant("FOREGROUND_GREEN")| Win32::Console::API.constant("FOREGROUND_INTENSITY") FG_GRAY = Win32::Console::API.constant("FOREGROUND_RED")| Win32::Console::API.constant("FOREGROUND_GREEN")| Win32::Console::API.constant("FOREGROUND_BLUE") FG_WHITE = Win32::Console::API.constant("FOREGROUND_RED")| Win32::Console::API.constant("FOREGROUND_GREEN")| Win32::Console::API.constant("FOREGROUND_BLUE")| Win32::Console::API.constant("FOREGROUND_INTENSITY") BG_BLACK = 0 BG_BLUE = Win32::Console::API.constant("BACKGROUND_BLUE") BG_LIGHTBLUE = Win32::Console::API.constant("BACKGROUND_BLUE")| Win32::Console::API.constant("BACKGROUND_INTENSITY") BG_RED = Win32::Console::API.constant("BACKGROUND_RED") BG_LIGHTRED = Win32::Console::API.constant("BACKGROUND_RED")| Win32::Console::API.constant("BACKGROUND_INTENSITY") BG_GREEN = Win32::Console::API.constant("BACKGROUND_GREEN") BG_LIGHTGREEN = Win32::Console::API.constant("BACKGROUND_GREEN")| Win32::Console::API.constant("BACKGROUND_INTENSITY") BG_MAGENTA = Win32::Console::API.constant("BACKGROUND_RED")| Win32::Console::API.constant("BACKGROUND_BLUE") BG_LIGHTMAGENTA = Win32::Console::API.constant("BACKGROUND_RED")| Win32::Console::API.constant("BACKGROUND_BLUE")| Win32::Console::API.constant("BACKGROUND_INTENSITY") BG_CYAN = Win32::Console::API.constant("BACKGROUND_GREEN")| Win32::Console::API.constant("BACKGROUND_BLUE") BG_LIGHTCYAN = Win32::Console::API.constant("BACKGROUND_GREEN")| Win32::Console::API.constant("BACKGROUND_BLUE")| Win32::Console::API.constant("BACKGROUND_INTENSITY") BG_BROWN = Win32::Console::API.constant("BACKGROUND_RED")| Win32::Console::API.constant("BACKGROUND_GREEN") BG_YELLOW = Win32::Console::API.constant("BACKGROUND_RED")| Win32::Console::API.constant("BACKGROUND_GREEN")| Win32::Console::API.constant("BACKGROUND_INTENSITY") BG_GRAY = Win32::Console::API.constant("BACKGROUND_RED")| Win32::Console::API.constant("BACKGROUND_GREEN")| Win32::Console::API.constant("BACKGROUND_BLUE") BG_WHITE = Win32::Console::API.constant("BACKGROUND_RED")| Win32::Console::API.constant("BACKGROUND_GREEN")| Win32::Console::API.constant("BACKGROUND_BLUE")| Win32::Console::API.constant("BACKGROUND_INTENSITY") ATTR_NORMAL = FG_GRAY | BG_BLACK ATTR_INVERSE = FG_BLACK | BG_GRAY include Win32::Console::Constants rubyworks-ansi-291cecc/work/reference/console/lib/Win32/Console/000077500000000000000000000000001516262404200246425ustar00rootroot00000000000000rubyworks-ansi-291cecc/work/reference/console/lib/Win32/Console/ANSI.rb000066400000000000000000000261731516262404200257320ustar00rootroot00000000000000# # Win32::Console::ANSI # # Copyright 2004 - Gonzalo Garramuno # Licensed under GNU General Public License or Perl's Artistic License # # Based on Perl's Win32::Console::ANSI # Copyright (c) 2003 Jean-Louis Morel # Licensed under GNU General Public License or Perl's Artistic License # require "win32/Console" module Win32 class Console module ANSI class IO < IO VERSION = '0.05' DEBUG = nil require "win32/registry" include Win32::Console::Constants # @todo: encode is another perl module EncodeOk = false # Retrieving the codepages cpANSI = nil Win32::Registry::HKEY_LOCAL_MACHINE.open('SYSTEM\CurrentControlSet\Control\Nls\CodePage' ) { |reg| cpANSI = reg['ACP'] } STDERR.puts "Unable to read Win codepage #{cpANSI}" if DEBUG && !cpANSI cpANSI = 'cp'+(cpANSI ? cpANSI : '1252') # Windows codepage OEM = Win32::Console::OutputCP() cpOEM = 'cp' + OEM.to_s # DOS codepage @@cp = cpANSI + cpOEM STDERR.puts "EncodeOk=#{EncodeOk} cpANSI=#{cpANSI} "+ "cpOEM=#{cpOEM}" if DEBUG @@color = { 30 => 0, # black foreground 31 => FOREGROUND_RED, # red foreground 32 => FOREGROUND_GREEN, # green foreground 33 => FOREGROUND_RED|FOREGROUND_GREEN, # yellow foreground 34 => FOREGROUND_BLUE, # blue foreground 35 => FOREGROUND_BLUE|FOREGROUND_RED, # magenta foreground 36 => FOREGROUND_BLUE|FOREGROUND_GREEN, # cyan foreground 37 => FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE, # white foreground 40 => 0, # black background 41 => BACKGROUND_RED, # red background 42 => BACKGROUND_GREEN, # green background 43 => BACKGROUND_RED|BACKGROUND_GREEN, # yellow background 44 => BACKGROUND_BLUE, # blue background 45 => BACKGROUND_BLUE|BACKGROUND_RED, # magenta background 46 => BACKGROUND_BLUE|BACKGROUND_GREEN, # cyan background 47 => BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE, # white background } def initialize super(1,'w') @Out = Win32::Console.new(STD_OUTPUT_HANDLE) @x = @y = 0 # to save cursor position @foreground = 7 @background = 0 @bold = @underline = @revideo = @concealed = nil @conv = 1 # char conversion by default end def write(*s) s.each { |x| _PrintString(x) } end private def _PrintString(t) s = t.dup while s != '' if s.sub!( /([^\e]*)?\e([\[\(])([0-9\;\=]*)([a-zA-Z@])(.*)/s,'\5') @Out.Write((_conv("#$1"))) if $2 == '[' case $4 when 'm' # ESC[#;#;....;#m Set display attributes attributs = $3.split(';') attributs.push(nil) unless attributs # ESC[m == ESC[;m ==...==ESC[0m for attr in attributs atv = attr.to_i if atv > 0 if atv == 1 @bold = 1 elsif atv == 21 @bold = nil elsif atv == 4 @underline = 1 elsif atv == 24 @underline = nil elsif atv == 7 @revideo = 1 elsif atv == 27 @revideo = nil elsif atv == 8 @concealed = 1 elsif atv == 28 @concealed = nil elsif atv >= 30 and atv <= 37 @foreground = atv - 30 elsif atv >=40 and atv <=47 @background = atv - 40 end else # ESC[0m reset @foreground = 7 @background = 0 @bold = @underline = @revideo = @concealed = nil end end if @revideo attribut = @@color[40+@foreground] | @@color[30+@background] else attribut = @@color[30+@foreground] | @@color[40+@background] end attribut |= FOREGROUND_INTENSITY if @bold attribut |= BACKGROUND_INTENSITY if @underline @Out.Attr(attribut) when 'J' if !$3 or $3 == '' # ESC[0J from cursor to end of display info = @Out.Info() s = ' ' * ((info[1]-info[3]-1)*info[0]+info[0]-info[2]-1) @Out.WriteChar(s, info[2], info[3]) @Out.Cursor(info[2], info[3]) elsif $3 == '1' # ESC[1J erase from start to cursor. info = @Out.Info() s = ' ' * (info[3]*info[0]+info[2]+1) @Out.WriteChar(s, 0, 0) @Out.Cursor(info[2], info[3]) elsif $3 == '2' # ESC[2J Clear screen and home cursor @Out.Cls() @Out.Cursor(0, 0) else STDERR.print "\e#$2#$3#$4" if DEBUG # if ESC-code not implemented end when 'K' info = @Out.Info() if !$3 or $3 == '' # ESC[0K Clear to end of line s = ' ' * (info[7]-info[2]+1) @Out.Write(s) @Out.Cursor(info[2], info[3]) elsif $3=='1' # ESC[1K Clear from start of line to cursor s = ' '*(info[2]+1) @Out.WriteChar(s, 0, info[3]) @Out.Cursor(info[2], info[3]) elsif $3=='2' # ESC[2K Clear whole line. s = ' '* info[0] @Out.WriteChar(s, 0, info[3]) @Out.Cursor(info[2], info[3]) end when 'L' # ESC[#L Insert # blank lines. n = $3 == ''? 1 : $3.to_i # ESC[L == ESC[1L info = @Out.Info() @Out.Scroll(0, info[3], info[0]-1, info[1]-1, 0, info[3] + n.to_i, ' '[0], @Out.Attr(), 0, 0, 10000, 10000) @Out.Cursor(info[2], info[3]) when 'M' # ESC[#M Delete # line. n = $3 == ''? 1 : $3.to_i # ESC[M == ESC[1M info = @Out.Info(); @Out.Scroll(0, info[3]+n, info[0]-1, info[1]-1, 0, info[3], ' '[0], @Out.Attr(), 0, 0, 10000, 10000) @Out.Cursor(info[2], info[3]) when 'P' # ESC[#P Delete # characters. n = $3 == ''? 1 : $3.to_i # ESC[P == ESC[1P info = @Out.Info() n = info[0]-info[2] if info[2]+n > info[0]-1 @Out.Scroll(info[2]+n, info[3] , info[0]-1, info[3], info[2], info[3], ' '[0], @Out.Attr(), 0, 0, 10000, 10000) s = ' ' * n @Out.Cursor(info[0]-n, info[3]) @Out.Write(s) @Out.Cursor(info[2], info[3]) when '@' # ESC[#@ Insert # blank Characters s = ' ' * $3.to_i info = @Out.Info() s << @Out.ReadChar(info[7]-info[2]+1, info[2], info[3]) s = s[0..-($3.to_i)] @Out.Write(s); @Out.Cursor(info[2], info[3]) when 'A' # ESC[#A Moves cursor up # lines (x, y) = @Out.Cursor() n = $3 == ''? 1 : $3.to_i; # ESC[A == ESC[1A @Out.Cursor(x, y-n) when 'B' # ESC[#B Moves cursor down # lines (x, y) = @Out.Cursor() n = $3 == ''? 1 : $3.to_i; # ESC[B == ESC[1B @Out.Cursor(x, y+n) when 'C' # ESC[#C Moves cursor forward # spaces (x, y) = @Out.Cursor() n = $3 == ''? 1 : $3.to_i; # ESC[C == ESC[1C @Out.Cursor(x+n, y) when 'D' # ESC[#D Moves cursor back # spaces (x, y) = @Out.Cursor() n = $3 == ''? 1 : $3.to_i; # ESC[D == ESC[1D @Out.Cursor(x-n, y) when 'E' # ESC[#E Moves cursor down # lines, column 1. x, y = @Out.Cursor() n = $3 == ''? 1 : $3.to_i; # ESC[E == ESC[1E @Out.Cursor(0, y+n) when 'F' # ESC[#F Moves cursor up # lines, column 1. x, y = @Out.Cursor() n = $3 == ''? 1 : $3.to_i; # ESC[F == ESC[1F @Out.Cursor(0, y-n) when 'G' # ESC[#G Moves cursor column # in current row. x, y = @Out.Cursor() n = $3 == ''? 1 : $3.to_i; # ESC[G == ESC[1G @Out.Cursor(n-1, y) when 'f' # ESC[#;#f Moves cursor to line #, column # y, x = $3.split(';') x = 1 unless x # ESC[;5H == ESC[1;5H ...etc y = 1 unless y @Out.Cursor(x.to_i-1, y.to_i-1) # origin (0,0) in DOS console when 'H' # ESC[#;#H Moves cursor to line #, column # y, x = $3.split(';') x = 1 unless x # ESC[;5H == ESC[1;5H ...etc y = 1 unless y @Out.Cursor(x.to_i-1, y.to_i-1) # origin (0,0) in DOS console when 's' # ESC[s Saves cursor position for recall later (@x, @y) = @Out.Cursor() when 'u' # ESC[u Return to saved cursor position @Out.Cursor(@x, @y) else STDERR.puts "\e#$2#$3#$4 not implemented" if DEBUG # ESC-code not implemented end else case $4 when 'U' # ESC(U no mapping @conv = nil when 'K' # ESC(K mapping if it exist @Out.OutputCP(OEM) # restore original codepage @conv = 1 when 'X' # ESC(#X codepage **EXPERIMENTAL** @conv = nil @Out.OutputCP($3) else STDERR.puts "\e#$2#$3#$4 not implemented" if DEBUG # ESC-code not implemented end end else @Out.Write(_conv(s)) s='' end end end def _conv(s) if @concealed s.gsub!( /\S/,' ') elsif @conv if EncodeOk from_to(s, cpANSI, cpOEM) elsif @@cp == 'cp1252cp850' # WinLatin1 --> DOSLatin1 s.tr!("ÁāŁƁǁȁɁʁˁ́́΁ρЁсҁӁԁՁցׁ؁فځہ܁݁ށ߁","?????????????????????????????ρ݁󁨁ǎԐҁӁށցׁ؁с噞ꚁᅁƄЁ䔁") elsif @@cp == 'cp1252cp437' # WinLatin1 --> DOSLatinUS s.tr!("ÁāŁƁǁȁɁʁˁ́́΁ρЁсҁӁԁՁցׁ؁فځہ܁݁ށ߁", "???????????????????????????????????????????????????????????????????ᅁ??????") elsif @@cp == 'cp1250cp852' # WinLatin2 --> DOSLatin2 s.tr!("ÁāŁƁǁȁɁʁˁ́́΁ρЁсҁӁԁՁցׁ؁فځہ܁݁ށ߁", "??????????????????????ρ???????񖁾聵ƎӁցׁҁсՁ⊙ށ뚁݁ꁠDŽ؁ԁЁ偢" ) elsif @@cp == 'cp1251cp855' # WinCyrillic --> DOSCyrillic s.tr!("ÁāŁƁǁȁɁʁˁ́́΁ρЁсҁӁԁՁցׁ؁فځہ܁݁ށ߁", "?????????????????????????????쁭􁸁ǁсӁՁׁ݁聫끬󁷁ƁЁҁԁց؁灪") end end return s end end # end print overloading end end end $stdout = Win32::Console::ANSI::IO.new() rubyworks-ansi-291cecc/work/reference/console/test/000077500000000000000000000000001516262404200225475ustar00rootroot00000000000000rubyworks-ansi-291cecc/work/reference/console/test/.CODE.rb000066400000000000000000001132221516262404200236650ustar00rootroot00000000000000 @_deferred = [] @_errormsg = nil @_finished = nil begin def defer(&i) @_deferred.push( i ) end def reject(*i) if !i || i[0] @_errormsg = i[1] if i[1] throw :paramout end end def finish(i) if !i || i[0] @_finished = 1 end end @unused = [] @cache = {} _FOUND_ = {} _errors = 0 _invalid = {} _lastprefix = nil _pos = 0 # current position to match from _nextpos = 0 # next position to match from catch(:alldone) do while !@_finished begin catch(:arg) do @_errormsg = nil # This is used for clustering of flags while _lastprefix substr = _args[_nextpos..-1] substr =~ /^(?!\s|\0|\Z)(?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)/ or begin _lastprefix=nil break end "#{_lastprefix}#{substr}" =~ /^((?:\-r|\-no_directories|\-nd|\-no_sequences|\-ns|\-no_movies|\-nm|\-no_files|\-nf|\-m|\-full_path|\-fp|\-fmt|\-color_directories|\-cd|\-color_sequences|\-cs|\-color_movies|\-cm|\-color_files|\-cf))/ or begin _lastprefix=nil break end _args = _args[0.._nextpos-1] + _lastprefix + _args[_nextpos..-1] break end # while _lastprefix _pos = _nextpos if _args usage(0) if _args && gindex(_args,/\G(--HELP|--Help|-HELP|-Help|-help|-H|-h|--help)(\s|\0|\Z)/,_pos) version(0) if _args && _args =~ /(-version|-VERSION|-Version|--VERSION|--Version|--version|-V|-v)(\s|\0|\Z)/ catch(:paramout) do while !_FOUND_['-color_directories'] begin catch(:param) do _pos = _nextpos if _args _PUNCT_ = {} _args && _pos = gindex( _args, /\G(?:\s|\0)*\-color_directories/i, _pos) or throw(:paramout) unless @_errormsg @_errormsg = %q|incorrect specification of '-color_directories' parameter| end _PARAM_ = '-color_directories' _args && _pos = gindex( _args, /\G(?:\s|\0)*((?:(?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)(?:(?:clear|reset|bold|dark|italic|underline|underscore|blink|rapid_blink|negative|concealed|strikethrough|black|red|green|yellow|blue|magenta|cyan|white|on_black|on_red|on_green|on_yellow|on_blue|on_magenta|on_cyan|on_white))))/xi, _pos ) or throw(:paramout) _VAR_ = %q|| _VAL_ = @@m[0] _VAL_.tr!("\0"," ") if _VAL_ c = _VAL_ if _invalid.has_key?('-color_directories') @_errormsg = %q|parameter '-color_directories' not allowed with parameter '| + _invalid['-color_directories'] + %q|'| throw(:paramout) else for i in [] _invalid[i] = '-color_directories' end end #if/then @cache['-cd'] = c @cache['-color_directories'] = c _lastprefix = "\-" _FOUND_['-color_directories'] = 1 throw :arg if _pos > 0 _nextpos = _args.length() throw :alldone end # catch(:param) end # begin end # while end # catch(:paramout) catch(:paramout) do while !_FOUND_['-color_sequences'] begin catch(:param) do _pos = _nextpos if _args _PUNCT_ = {} _args && _pos = gindex( _args, /\G(?:\s|\0)*\-color_sequences/i, _pos) or throw(:paramout) unless @_errormsg @_errormsg = %q|incorrect specification of '-color_sequences' parameter| end _PARAM_ = '-color_sequences' _args && _pos = gindex( _args, /\G(?:\s|\0)*((?:(?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)(?:(?:clear|reset|bold|dark|italic|underline|underscore|blink|rapid_blink|negative|concealed|strikethrough|black|red|green|yellow|blue|magenta|cyan|white|on_black|on_red|on_green|on_yellow|on_blue|on_magenta|on_cyan|on_white))))/xi, _pos ) or throw(:paramout) _VAR_ = %q|| _VAL_ = @@m[0] _VAL_.tr!("\0"," ") if _VAL_ c = _VAL_ if _invalid.has_key?('-color_sequences') @_errormsg = %q|parameter '-color_sequences' not allowed with parameter '| + _invalid['-color_sequences'] + %q|'| throw(:paramout) else for i in [] _invalid[i] = '-color_sequences' end end #if/then @cache['-cs'] = c @cache['-color_sequences'] = c _lastprefix = "\-" _FOUND_['-color_sequences'] = 1 throw :arg if _pos > 0 _nextpos = _args.length() throw :alldone end # catch(:param) end # begin end # while end # catch(:paramout) catch(:paramout) do while !_FOUND_['-no_directories'] begin catch(:param) do _pos = _nextpos if _args _PUNCT_ = {} _args && _pos = gindex( _args, /\G(?:\s|\0)*\-no_directories/i, _pos) or throw(:paramout) unless @_errormsg @_errormsg = %q|incorrect specification of '-no_directories' parameter| end _PARAM_ = '-no_directories' _args && _pos = gindex( _args, /\G/xi, _pos ) or throw(:paramout) if _invalid.has_key?('-no_directories') @_errormsg = %q|parameter '-no_directories' not allowed with parameter '| + _invalid['-no_directories'] + %q|'| throw(:paramout) else for i in [] _invalid[i] = '-no_directories' end end #if/then @cache['-nd'] = '-nd' @cache['-no_directories'] = '-no_directories' _lastprefix = "\-" _FOUND_['-no_directories'] = 1 throw :arg if _pos > 0 _nextpos = _args.length() throw :alldone end # catch(:param) end # begin end # while end # catch(:paramout) catch(:paramout) do while !_FOUND_['-color_movies'] begin catch(:param) do _pos = _nextpos if _args _PUNCT_ = {} _args && _pos = gindex( _args, /\G(?:\s|\0)*\-color_movies/i, _pos) or throw(:paramout) unless @_errormsg @_errormsg = %q|incorrect specification of '-color_movies' parameter| end _PARAM_ = '-color_movies' _args && _pos = gindex( _args, /\G(?:\s|\0)*((?:(?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)(?:(?:clear|reset|bold|dark|italic|underline|underscore|blink|rapid_blink|negative|concealed|strikethrough|black|red|green|yellow|blue|magenta|cyan|white|on_black|on_red|on_green|on_yellow|on_blue|on_magenta|on_cyan|on_white))))/xi, _pos ) or throw(:paramout) _VAR_ = %q|| _VAL_ = @@m[0] _VAL_.tr!("\0"," ") if _VAL_ c = _VAL_ if _invalid.has_key?('-color_movies') @_errormsg = %q|parameter '-color_movies' not allowed with parameter '| + _invalid['-color_movies'] + %q|'| throw(:paramout) else for i in [] _invalid[i] = '-color_movies' end end #if/then @cache['-cm'] = c @cache['-color_movies'] = c _lastprefix = "\-" _FOUND_['-color_movies'] = 1 throw :arg if _pos > 0 _nextpos = _args.length() throw :alldone end # catch(:param) end # begin end # while end # catch(:paramout) catch(:paramout) do while !_FOUND_['-no_sequences'] begin catch(:param) do _pos = _nextpos if _args _PUNCT_ = {} _args && _pos = gindex( _args, /\G(?:\s|\0)*\-no_sequences/i, _pos) or throw(:paramout) unless @_errormsg @_errormsg = %q|incorrect specification of '-no_sequences' parameter| end _PARAM_ = '-no_sequences' _args && _pos = gindex( _args, /\G/xi, _pos ) or throw(:paramout) if _invalid.has_key?('-no_sequences') @_errormsg = %q|parameter '-no_sequences' not allowed with parameter '| + _invalid['-no_sequences'] + %q|'| throw(:paramout) else for i in [] _invalid[i] = '-no_sequences' end end #if/then @cache['-ns'] = '-ns' @cache['-no_sequences'] = '-no_sequences' _lastprefix = "\-" _FOUND_['-no_sequences'] = 1 throw :arg if _pos > 0 _nextpos = _args.length() throw :alldone end # catch(:param) end # begin end # while end # catch(:paramout) catch(:paramout) do while !_FOUND_['-color_files'] begin catch(:param) do _pos = _nextpos if _args _PUNCT_ = {} _args && _pos = gindex( _args, /\G(?:\s|\0)*\-color_files/i, _pos) or throw(:paramout) unless @_errormsg @_errormsg = %q|incorrect specification of '-color_files' parameter| end _PARAM_ = '-color_files' _args && _pos = gindex( _args, /\G(?:\s|\0)*((?:(?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)(?:(?:clear|reset|bold|dark|italic|underline|underscore|blink|rapid_blink|negative|concealed|strikethrough|black|red|green|yellow|blue|magenta|cyan|white|on_black|on_red|on_green|on_yellow|on_blue|on_magenta|on_cyan|on_white))))/xi, _pos ) or throw(:paramout) _VAR_ = %q|| _VAL_ = @@m[0] _VAL_.tr!("\0"," ") if _VAL_ c = _VAL_ if _invalid.has_key?('-color_files') @_errormsg = %q|parameter '-color_files' not allowed with parameter '| + _invalid['-color_files'] + %q|'| throw(:paramout) else for i in [] _invalid[i] = '-color_files' end end #if/then @cache['-cf'] = c @cache['-color_files'] = c _lastprefix = "\-" _FOUND_['-color_files'] = 1 throw :arg if _pos > 0 _nextpos = _args.length() throw :alldone end # catch(:param) end # begin end # while end # catch(:paramout) catch(:paramout) do while !_FOUND_['-no_movies'] begin catch(:param) do _pos = _nextpos if _args _PUNCT_ = {} _args && _pos = gindex( _args, /\G(?:\s|\0)*\-no_movies/i, _pos) or throw(:paramout) unless @_errormsg @_errormsg = %q|incorrect specification of '-no_movies' parameter| end _PARAM_ = '-no_movies' _args && _pos = gindex( _args, /\G/xi, _pos ) or throw(:paramout) if _invalid.has_key?('-no_movies') @_errormsg = %q|parameter '-no_movies' not allowed with parameter '| + _invalid['-no_movies'] + %q|'| throw(:paramout) else for i in [] _invalid[i] = '-no_movies' end end #if/then @cache['-nm'] = '-nm' @cache['-no_movies'] = '-no_movies' _lastprefix = "\-" _FOUND_['-no_movies'] = 1 throw :arg if _pos > 0 _nextpos = _args.length() throw :alldone end # catch(:param) end # begin end # while end # catch(:paramout) catch(:paramout) do while !_FOUND_['-full_path'] begin catch(:param) do _pos = _nextpos if _args _PUNCT_ = {} _args && _pos = gindex( _args, /\G(?:\s|\0)*\-full_path/i, _pos) or throw(:paramout) unless @_errormsg @_errormsg = %q|incorrect specification of '-full_path' parameter| end _PARAM_ = '-full_path' _args && _pos = gindex( _args, /\G(?:()(?:\s|\0)*((?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)s)())?/xi, _pos ) or throw(:paramout) if @@m[1] && !@@m[1].empty? _PUNCT_['s'] = @@m[1] end if _invalid.has_key?('-full_path') @_errormsg = %q|parameter '-full_path' not allowed with parameter '| + _invalid['-full_path'] + %q|'| throw(:paramout) else for i in [] _invalid[i] = '-full_path' end end #if/then @cache['-full_path'] = _PUNCT_['s'] || 1 _lastprefix = "\-" _FOUND_['-full_path'] = 1 throw :arg if _pos > 0 _nextpos = _args.length() throw :alldone end # catch(:param) end # begin end # while end # catch(:paramout) catch(:paramout) do while !_FOUND_['-no_files'] begin catch(:param) do _pos = _nextpos if _args _PUNCT_ = {} _args && _pos = gindex( _args, /\G(?:\s|\0)*\-no_files/i, _pos) or throw(:paramout) unless @_errormsg @_errormsg = %q|incorrect specification of '-no_files' parameter| end _PARAM_ = '-no_files' _args && _pos = gindex( _args, /\G/xi, _pos ) or throw(:paramout) if _invalid.has_key?('-no_files') @_errormsg = %q|parameter '-no_files' not allowed with parameter '| + _invalid['-no_files'] + %q|'| throw(:paramout) else for i in [] _invalid[i] = '-no_files' end end #if/then @cache['-nf'] = '-nf' @cache['-no_files'] = '-no_files' _lastprefix = "\-" _FOUND_['-no_files'] = 1 throw :arg if _pos > 0 _nextpos = _args.length() throw :alldone end # catch(:param) end # begin end # while end # catch(:paramout) catch(:paramout) do while !_FOUND_['-fmt'] begin catch(:param) do _pos = _nextpos if _args _PUNCT_ = {} _args && _pos = gindex( _args, /\G(?:\s|\0)*\-fmt/i, _pos) or throw(:paramout) unless @_errormsg @_errormsg = %q|incorrect specification of '-fmt' parameter| end _PARAM_ = '-fmt' _args && _pos = gindex( _args, /\G(?:\s|\0)*((?:(?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)ilm|dd|shake))/xi, _pos ) or throw(:paramout) _VAR_ = %q|

    | _VAL_ = @@m[0] _VAL_.tr!("\0"," ") if _VAL_ p = _VAL_ if _invalid.has_key?('-fmt') @_errormsg = %q|parameter '-fmt' not allowed with parameter '| + _invalid['-fmt'] + %q|'| throw(:paramout) else for i in [] _invalid[i] = '-fmt' end end #if/then @cache['-fmt'] = p _lastprefix = "\-" _FOUND_['-fmt'] = 1 throw :arg if _pos > 0 _nextpos = _args.length() throw :alldone end # catch(:param) end # begin end # while end # catch(:paramout) catch(:paramout) do while !_FOUND_['-cf'] begin catch(:param) do _pos = _nextpos if _args _PUNCT_ = {} _args && _pos = gindex( _args, /\G(?:\s|\0)*\-cf/i, _pos) or throw(:paramout) unless @_errormsg @_errormsg = %q|incorrect specification of '-cf' parameter| end _PARAM_ = '-cf' _args && _pos = gindex( _args, /\G(?:\s|\0)*((?:(?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)(?:(?:clear|reset|bold|dark|italic|underline|underscore|blink|rapid_blink|negative|concealed|strikethrough|black|red|green|yellow|blue|magenta|cyan|white|on_black|on_red|on_green|on_yellow|on_blue|on_magenta|on_cyan|on_white))))/xi, _pos ) or throw(:paramout) _VAR_ = %q|| _VAL_ = @@m[0] _VAL_.tr!("\0"," ") if _VAL_ c = _VAL_ if _invalid.has_key?('-cf') @_errormsg = %q|parameter '-cf' not allowed with parameter '| + _invalid['-cf'] + %q|'| throw(:paramout) else for i in [] _invalid[i] = '-cf' end end #if/then @cache['-cf'] = c @cache['-cf'] = c _lastprefix = "\-" _FOUND_['-cf'] = 1 throw :arg if _pos > 0 _nextpos = _args.length() throw :alldone end # catch(:param) end # begin end # while end # catch(:paramout) catch(:paramout) do while !_FOUND_['-nf'] begin catch(:param) do _pos = _nextpos if _args _PUNCT_ = {} _args && _pos = gindex( _args, /\G(?:\s|\0)*\-nf/i, _pos) or throw(:paramout) unless @_errormsg @_errormsg = %q|incorrect specification of '-nf' parameter| end _PARAM_ = '-nf' _args && _pos = gindex( _args, /\G/xi, _pos ) or throw(:paramout) if _invalid.has_key?('-nf') @_errormsg = %q|parameter '-nf' not allowed with parameter '| + _invalid['-nf'] + %q|'| throw(:paramout) else for i in [] _invalid[i] = '-nf' end end #if/then @cache['-nf'] = '-nf' _lastprefix = "\-" _FOUND_['-nf'] = 1 throw :arg if _pos > 0 _nextpos = _args.length() throw :alldone end # catch(:param) end # begin end # while end # catch(:paramout) catch(:paramout) do while !_FOUND_['-nm'] begin catch(:param) do _pos = _nextpos if _args _PUNCT_ = {} _args && _pos = gindex( _args, /\G(?:\s|\0)*\-nm/i, _pos) or throw(:paramout) unless @_errormsg @_errormsg = %q|incorrect specification of '-nm' parameter| end _PARAM_ = '-nm' _args && _pos = gindex( _args, /\G/xi, _pos ) or throw(:paramout) if _invalid.has_key?('-nm') @_errormsg = %q|parameter '-nm' not allowed with parameter '| + _invalid['-nm'] + %q|'| throw(:paramout) else for i in [] _invalid[i] = '-nm' end end #if/then @cache['-nm'] = '-nm' _lastprefix = "\-" _FOUND_['-nm'] = 1 throw :arg if _pos > 0 _nextpos = _args.length() throw :alldone end # catch(:param) end # begin end # while end # catch(:paramout) catch(:paramout) do while !_FOUND_['-ns'] begin catch(:param) do _pos = _nextpos if _args _PUNCT_ = {} _args && _pos = gindex( _args, /\G(?:\s|\0)*\-ns/i, _pos) or throw(:paramout) unless @_errormsg @_errormsg = %q|incorrect specification of '-ns' parameter| end _PARAM_ = '-ns' _args && _pos = gindex( _args, /\G/xi, _pos ) or throw(:paramout) if _invalid.has_key?('-ns') @_errormsg = %q|parameter '-ns' not allowed with parameter '| + _invalid['-ns'] + %q|'| throw(:paramout) else for i in [] _invalid[i] = '-ns' end end #if/then @cache['-ns'] = '-ns' _lastprefix = "\-" _FOUND_['-ns'] = 1 throw :arg if _pos > 0 _nextpos = _args.length() throw :alldone end # catch(:param) end # begin end # while end # catch(:paramout) catch(:paramout) do while !_FOUND_['-cd'] begin catch(:param) do _pos = _nextpos if _args _PUNCT_ = {} _args && _pos = gindex( _args, /\G(?:\s|\0)*\-cd/i, _pos) or throw(:paramout) unless @_errormsg @_errormsg = %q|incorrect specification of '-cd' parameter| end _PARAM_ = '-cd' _args && _pos = gindex( _args, /\G(?:\s|\0)*((?:(?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)(?:(?:clear|reset|bold|dark|italic|underline|underscore|blink|rapid_blink|negative|concealed|strikethrough|black|red|green|yellow|blue|magenta|cyan|white|on_black|on_red|on_green|on_yellow|on_blue|on_magenta|on_cyan|on_white))))/xi, _pos ) or throw(:paramout) _VAR_ = %q|| _VAL_ = @@m[0] _VAL_.tr!("\0"," ") if _VAL_ c = _VAL_ if _invalid.has_key?('-cd') @_errormsg = %q|parameter '-cd' not allowed with parameter '| + _invalid['-cd'] + %q|'| throw(:paramout) else for i in [] _invalid[i] = '-cd' end end #if/then @cache['-cd'] = c @cache['-cd'] = c _lastprefix = "\-" _FOUND_['-cd'] = 1 throw :arg if _pos > 0 _nextpos = _args.length() throw :alldone end # catch(:param) end # begin end # while end # catch(:paramout) catch(:paramout) do while !_FOUND_['-nd'] begin catch(:param) do _pos = _nextpos if _args _PUNCT_ = {} _args && _pos = gindex( _args, /\G(?:\s|\0)*\-nd/i, _pos) or throw(:paramout) unless @_errormsg @_errormsg = %q|incorrect specification of '-nd' parameter| end _PARAM_ = '-nd' _args && _pos = gindex( _args, /\G/xi, _pos ) or throw(:paramout) if _invalid.has_key?('-nd') @_errormsg = %q|parameter '-nd' not allowed with parameter '| + _invalid['-nd'] + %q|'| throw(:paramout) else for i in [] _invalid[i] = '-nd' end end #if/then @cache['-nd'] = '-nd' _lastprefix = "\-" _FOUND_['-nd'] = 1 throw :arg if _pos > 0 _nextpos = _args.length() throw :alldone end # catch(:param) end # begin end # while end # catch(:paramout) catch(:paramout) do while !_FOUND_['-cs'] begin catch(:param) do _pos = _nextpos if _args _PUNCT_ = {} _args && _pos = gindex( _args, /\G(?:\s|\0)*\-cs/i, _pos) or throw(:paramout) unless @_errormsg @_errormsg = %q|incorrect specification of '-cs' parameter| end _PARAM_ = '-cs' _args && _pos = gindex( _args, /\G(?:\s|\0)*((?:(?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)(?:(?:clear|reset|bold|dark|italic|underline|underscore|blink|rapid_blink|negative|concealed|strikethrough|black|red|green|yellow|blue|magenta|cyan|white|on_black|on_red|on_green|on_yellow|on_blue|on_magenta|on_cyan|on_white))))/xi, _pos ) or throw(:paramout) _VAR_ = %q|| _VAL_ = @@m[0] _VAL_.tr!("\0"," ") if _VAL_ c = _VAL_ if _invalid.has_key?('-cs') @_errormsg = %q|parameter '-cs' not allowed with parameter '| + _invalid['-cs'] + %q|'| throw(:paramout) else for i in [] _invalid[i] = '-cs' end end #if/then @cache['-cs'] = c @cache['-cs'] = c _lastprefix = "\-" _FOUND_['-cs'] = 1 throw :arg if _pos > 0 _nextpos = _args.length() throw :alldone end # catch(:param) end # begin end # while end # catch(:paramout) catch(:paramout) do while !_FOUND_['-fp'] begin catch(:param) do _pos = _nextpos if _args _PUNCT_ = {} _args && _pos = gindex( _args, /\G(?:\s|\0)*\-fp/i, _pos) or throw(:paramout) unless @_errormsg @_errormsg = %q|incorrect specification of '-fp' parameter| end _PARAM_ = '-fp' _args && _pos = gindex( _args, /\G/xi, _pos ) or throw(:paramout) if _invalid.has_key?('-fp') @_errormsg = %q|parameter '-fp' not allowed with parameter '| + _invalid['-fp'] + %q|'| throw(:paramout) else for i in [] _invalid[i] = '-fp' end end #if/then @cache['-fp'] = '-fp' _lastprefix = "\-" _FOUND_['-fp'] = 1 throw :arg if _pos > 0 _nextpos = _args.length() throw :alldone end # catch(:param) end # begin end # while end # catch(:paramout) catch(:paramout) do while !_FOUND_['-cm'] begin catch(:param) do _pos = _nextpos if _args _PUNCT_ = {} _args && _pos = gindex( _args, /\G(?:\s|\0)*\-cm/i, _pos) or throw(:paramout) unless @_errormsg @_errormsg = %q|incorrect specification of '-cm' parameter| end _PARAM_ = '-cm' _args && _pos = gindex( _args, /\G(?:\s|\0)*((?:(?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)(?:(?:clear|reset|bold|dark|italic|underline|underscore|blink|rapid_blink|negative|concealed|strikethrough|black|red|green|yellow|blue|magenta|cyan|white|on_black|on_red|on_green|on_yellow|on_blue|on_magenta|on_cyan|on_white))))/xi, _pos ) or throw(:paramout) _VAR_ = %q|| _VAL_ = @@m[0] _VAL_.tr!("\0"," ") if _VAL_ c = _VAL_ if _invalid.has_key?('-cm') @_errormsg = %q|parameter '-cm' not allowed with parameter '| + _invalid['-cm'] + %q|'| throw(:paramout) else for i in [] _invalid[i] = '-cm' end end #if/then @cache['-cm'] = c @cache['-cm'] = c _lastprefix = "\-" _FOUND_['-cm'] = 1 throw :arg if _pos > 0 _nextpos = _args.length() throw :alldone end # catch(:param) end # begin end # while end # catch(:paramout) catch(:paramout) do while !_FOUND_['-r'] begin catch(:param) do _pos = _nextpos if _args _PUNCT_ = {} _args && _pos = gindex( _args, /\G(?:\s|\0)*\-r/i, _pos) or throw(:paramout) unless @_errormsg @_errormsg = %q|incorrect specification of '-r' parameter| end _PARAM_ = '-r' _args && _pos = gindex( _args, /\G/xi, _pos ) or throw(:paramout) if _invalid.has_key?('-r') @_errormsg = %q|parameter '-r' not allowed with parameter '| + _invalid['-r'] + %q|'| throw(:paramout) else for i in [] _invalid[i] = '-r' end end #if/then @cache['-r'] = '-r' _lastprefix = "\-" _FOUND_['-r'] = 1 throw :arg if _pos > 0 _nextpos = _args.length() throw :alldone end # catch(:param) end # begin end # while end # catch(:paramout) catch(:paramout) do while !_FOUND_['-m'] begin catch(:param) do _pos = _nextpos if _args _PUNCT_ = {} _args && _pos = gindex( _args, /\G(?:\s|\0)*\-m/i, _pos) or throw(:paramout) unless @_errormsg @_errormsg = %q|incorrect specification of '-m' parameter| end _PARAM_ = '-m' _args && _pos = gindex( _args, /\G(?:()(?:\s|\0)*((?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)issing)())?/xi, _pos ) or throw(:paramout) if @@m[1] && !@@m[1].empty? _PUNCT_['issing'] = @@m[1] end if _invalid.has_key?('-m') @_errormsg = %q|parameter '-m' not allowed with parameter '| + _invalid['-m'] + %q|'| throw(:paramout) else for i in [] _invalid[i] = '-m' end end #if/then @cache['-m'] = _PUNCT_['issing'] || 1 _lastprefix = "\-" _FOUND_['-m'] = 1 throw :arg if _pos > 0 _nextpos = _args.length() throw :alldone end # catch(:param) end # begin end # while end # catch(:paramout) catch(:paramout) do while !_FOUND_[''] begin catch(:param) do _pos = _nextpos if _args _PUNCT_ = {} _args && _pos = gindex( _args, /\G(?:\s|\0)*/i, _pos) or throw(:paramout) unless @_errormsg @_errormsg = %q|incorrect specification of '' parameter| end _PARAM_ = '' _args && _pos = gindex( _args, /\G(?:()(?:\s|\0)*((?:(?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)(?:(?:\S|\0))+)(?:\s+(?:(?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)(?:(?:\S|\0))+))*)())?/xi, _pos ) or throw(:paramout) _VAR_ = %q|| _VAL_ = nil dirs = (@@m[1]||'').split(' ').map { |i| i.tr("\0", " ") } if _invalid.has_key?('') @_errormsg = %q|parameter '' not allowed with parameter '| + _invalid[''] + %q|'| throw(:paramout) else for i in [] _invalid[i] = '' end end #if/then @cache[''] = dirs _lastprefix = nil _FOUND_[''] = 1 throw :arg if _pos > 0 _nextpos = _args.length() throw :alldone end # catch(:param) end # begin end # while end # catch(:paramout) if _lastprefix _pos = _nextpos + _lastprefix.length() _lastprefix = nil next end _pos = _nextpos _args && _pos = gindex( _args, /\G(?:\s|\0)*(\S+)/, _pos ) or throw(:alldone) if @_errormsg $stderr.puts( "Error#{source}: #{@_errormsg}\n" ) else @unused.push( @@m[0] ) end _errors += 1 if @_errormsg end # catch(:arg) ensure # begin _pos = 0 if _pos.nil? _nextpos = _pos if _args if _args and _args.index( /\G(\s|\0)*\Z/, _pos ) _args = _get_nextline.call(self) if !@_finished throw(:alldone) unless _args _pos = _nextpos = 0 _lastprefix = '' end # if end # begin/ensure end # while @_finished end # catch(:alldone) end # begin #################### Add unused arguments if _args && _nextpos > 0 && _args.length() > 0 @unused.push( _args[_nextpos..-1].split(' ' ) ) end for i in @unused i.tr!( "\0", " " ) end #################### Print help hint if _errors > 0 && !@source.nil? $stderr.puts "\n(try '#$0 -help' for more information)" end ## cannot just assign unused to ARGV in ruby unless @source != '' ARGV.clear @unused.map { |i| ARGV.push(i) } end unless _errors > 0 for i in @_deferred begin i.call() rescue => e raise "Error: action in Getopt::Declare specification produced:\n" + e end end end !(_errors>0) # return true or false (false for errors) rubyworks-ansi-291cecc/work/reference/console/test/test_cursor.rb000077500000000000000000000002471516262404200254560ustar00rootroot00000000000000#!/usr/bin/env ruby require "Win32/Console" a = Win32::Console.new(STD_OUTPUT_HANDLE) puts "Setting cursor to visible and 100% fat" a.Cursor(-1,-1,100,1) rubyworks-ansi-291cecc/work/reference/console/test/test_mouse.rb000077500000000000000000000002071516262404200252650ustar00rootroot00000000000000#!/usr/bin/env ruby require "Win32/Console" a = Win32::Console.new() puts "# of Mouse buttons: #{Win32::Console.MouseButtons}" rubyworks-ansi-291cecc/work/reference/console/test/test_readinput.rb000077500000000000000000000024221516262404200261310ustar00rootroot00000000000000#!/usr/bin/env ruby require "Win32/Console" include Win32::Console::Constants a = Win32::Console.new(STD_INPUT_HANDLE) puts "InputChar: Type a phrase then ENTER, please:" x1 = a.InputChar(1) puts "Your phrase starts with the character #{x1}" fdwMode = ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT a.Mode(fdwMode) puts puts "PeekInput: Type a character without ENTER or do something, please:" while (x1 = a.PeekInput()).size < 1 end if x1[0] == KEY_EVENT puts "You typed #{x1[5]}='#{x1[5].chr}'" else print "You did not typed, but " case x1[0] when MOUSE_EVENT puts "used mouse" when WINDOW_BUFFER_SIZE_EVENT puts "resize window" when MENU_EVENT puts "called menu" when FOCUS_EVENT puts "changed focus" else puts "...should never get here" end end puts puts "Input (as PeekInput keeps event, this reuses PeekInput value):" x1 = a.Input() if x1[0] == KEY_EVENT puts "You typed #{x1[5]}='#{x1[5].chr}'" else print "You did not typed, but " case x1[0] when MOUSE_EVENT puts "used mouse" when WINDOW_BUFFER_SIZE_EVENT puts "resize window" when MENU_EVENT puts "called menu" when FOCUS_EVENT puts "changed focus" else puts "...should never get here" end end rubyworks-ansi-291cecc/work/reference/console/test/test_readoutput.rb000077500000000000000000000015751516262404200263420ustar00rootroot00000000000000#!/usr/bin/env ruby require "Win32/Console" include Win32::Console::Constants a = Win32::Console.new(STD_OUTPUT_HANDLE) puts <<'EOF' This is a simple test of test to grab from the console. Hopefully this will work easily and merrily. This is a simple test of test to grab from the console. Hopefully this will work easily and merrily. This is a simple test of test to grab from the console. Hopefully this will work easily and merrily. EOF x1 = a.ReadChar(10,10,10) x2 = a.ReadAttr(10,10,10) x3 = a.ReadRect(10,10,20,10) puts "ReadChar .#{x1}." puts x2.class, x2.size print "ReadAttr ." for i in x2 print "#{i}|" end print "\nReadRect ." i = 0 while i < x3.length-1 print "#{x3[i]}" i += 2 end print "\n " i = 1 while i < x3.length-1 print "#{x3[i]}|" i += 2 end print "\n" #puts "read=",x1 #print "Attributes:",x2 rubyworks-ansi-291cecc/work/reference/console/test/test_sendevent.rb000077500000000000000000000003341516262404200261310ustar00rootroot00000000000000#!/usr/bin/env ruby require "Win32/Console" i = 0 begin while i < 99 if i == 10 Win32::Console::GenerateCtrlEvent() end i = i.next end rescue Exception end puts "if i=10, then OK! i=#{i}" rubyworks-ansi-291cecc/work/reference/console/test/test_title.rb000077500000000000000000000003611516262404200252570ustar00rootroot00000000000000#!/usr/bin/env ruby require "Win32/Console" a = Win32::Console.new() title = a.Title() puts "Old title: \"#{title}\"" a.Title("This is a new title") title = a.Title() puts "I just changed the title to '#{title}'" sleep(5) rubyworks-ansi-291cecc/work/reference/console/test/test_write.rb000077500000000000000000000020621516262404200252700ustar00rootroot00000000000000#!/usr/bin/env ruby if $0 == __FILE__ require "Term/ANSIColor" include Term::ANSIColor require "benchmark" include Benchmark require "Win32/Console/ANSI" bm do |x| num = 100 x.report("#{num} times") { 0.upto(num) { print "\e[2J" print red, bold, "Usage as constants:", reset, "\n" print clear, "clear", reset, reset, "reset", reset, bold, "bold", reset, dark, "dark", reset, underscore, "underscore", reset, blink, "blink", reset, negative, "negative", reset, concealed, "concealed", reset, "|\n", black, "black", reset, red, "red", reset, green, "green", reset, yellow, "yellow", reset, blue, "blue", reset, magenta, "magenta", reset, cyan, "cyan", reset, white, "white", reset, "|\n", on_black, "on_black", reset, on_red, "on_red", reset, on_green, "on_green", reset, on_yellow, "on_yellow", reset, on_blue, "on_blue", reset, on_magenta, "on_magenta", reset, on_cyan, "on_cyan", reset, on_white, "on_white", reset, "|\n\n" print "\e[s\e[20P.................." } } end end rubyworks-ansi-291cecc/work/reference/heuristics.rb000066400000000000000000000011071516262404200226340ustar00rootroot00000000000000 def guess_color_availability return false unless @output.tty? case ENV["TERM"] when /term(?:-color)?\z/, "screen" true else return true if ENV["EMACS"] == "t" false end end def guess_progress_row_max term_width = guess_term_width if term_width.zero? if ENV["EMACS"] == "t" -1 else 79 end else term_width end end def guess_term_width Integer(ENV["COLUMNS"] || ENV["TERM_WIDTH"] || 0) rescue ArgumentError 0 end